관리 메뉴

bright jazz music

todo-react-app(front 예전) 본문

Framework/ReactJs

todo-react-app(front 예전)

bright jazz music 2023. 5. 23. 21:32
import { Container, List, Paper } from '@mui/material';
import './App.css';
import Todo from './Todo';
import React, { useState } from 'react';
import AddTodo from './AddTodo';

function App() {
  
  const [items, setItems] = useState([
    // {
    //   id: "0",
    //   title: "Hello World 1",
    //   done: true
    // },
    // {
    //   id: "1",
    //   title: "Hello World 2",
    //   done: true
    // }
  ]);

  //2. TodoList에 목록 추가하기
  const addItem = (item) => {
    item.id = "ID-" + items.length; //key를 위한 id
    item.done = false; //done 초기화
    //업데이트는 반드시 setItems로 하고 새 배열을 만들어야 한다.
    setItems([...items, item]);
    console.log("items : ", items);
  };

  //8. TodoList에서 목록 삭제하기
  const deleteItem = (item) => {
    //삭제할 아이템을 찾는다. filter로 제외
    const newItems =items.filter(e => e.id !== item.id);
    //삭제할 아이템을 제외한 아이템을 다시 배열에 저장한다.
    setItems([...newItems]);
  };

  //9. TodoList에서 목록 수정하기
  const editItem = () => {
    setItems([...items]);
  };


  //Todo와 연결해주기
  let todoItems =
    items.length > 0 && (
      <Paper style={{margin: 16}}>
        <List>
          {items.map((item) => (
            <Todo item={item} key={item.id} editItem={editItem} deleteItem={deleteItem}/>
          ))}
        </List>
      </Paper>
    );

    return  <div className="App">
              <Container maxWidth="md">
                {/* 3. AddTodo의 프로퍼티로 addItem 함수를 넘겨 AddTodo에서 이 함수를 사용한다. */}
                <AddTodo addItem={addItem}/>
                <div className='TodoList'>{todoItems}</div>
              </Container>
            </div>
}

export default App;

 

import { CheckBox } from "@mui/icons-material";
import { Checkbox, InputBase, ListItem, ListItemText, ListItemSecondaryAction, IconButton } from "@mui/material";
import DeleteOutlined from '@mui/icons-material/DeleteOutlined';
import React, { useState } from "react";


const Todo = (props) => {
    const [item, setItem] = useState(props.item);
    const [readOnly, setReadOnly] = useState(true);
    const deleteItem = props.deleteItem; //App.js에서 넘어온 deleteItem 함수를 저장
    const editItem = props.editItem; //App.js에서 넘어온 editItem 함수를 저장


    //deleteEventHandler 작성
    const deleteEventHandler = () => {
        deleteItem(item);
    };

    //turnOffReadOnly 함수 작성
    const turnOffReadOnly = () => {
        setReadOnly(false);
    };

    //turnOnReadOnly 함수 작성
    const turnOnreadOnly = (e) => {
        if(e.key === "Enter") {
            setReadOnly(true);
            
        }
    };

    //수정용 editEventHandler 작성
    const editEventHandler = (e) => {
        item.title = e.target.value;
        editItem();
    };

    //체크박스
    const checkBoxEventHandler = (e) => {
        item.done = e.target.checked;
        editItem();
    };


    return (
        <ListItem>
            <Checkbox checked={item.done} onChange={checkBoxEventHandler}/>
            <ListItemText>
                <InputBase
                    inputProps={{
                        "aria-label":"naked",
                        readOnly: readOnly}}
                    onClick={turnOffReadOnly}
                    onKeyDown={turnOnreadOnly}
                    onChange={editEventHandler}
                    type="text"
                    id={item.id}
                    name={item.id}
                    value={item.title}
                    multiline={true}
                    fullWidth={true} 
                />
            </ListItemText>
            <ListItemSecondaryAction>
                <IconButton aria-label="Delete Todo" onClick={deleteEventHandler}>
                    <DeleteOutlined />
                </IconButton>
            </ListItemSecondaryAction>
        </ListItem>
    );
};

export default Todo;

 

import React, { useState } from "react";
import {Button, Grid, TextField} from "@mui/material";

const AddTodo = (props) => {
    //사용자의 입력을 저장할 오브젝트
    const [item, setItem] = useState({title: ""});

    //이벤트 핸들러 함수인 onInputChange는 사용자가 입력한 값을 item 오브젝트에 저장한다. <== onChange
    const onInputChange = (e) => { //e는 이벤트 객체 Event e
        setItem({title: e.target.value});
        console.log(item);
        
    }

    //5.넘어온 addItem 함수를 변수에 저장
    const addItem = props.addItem;

    //6. onButtonClick 함수를 작성하고 addItem 함수를 호출 <== onClick
    const onButtonClick = () => {
        addItem(item);
        setItem({title: ""});
    }

    //7. 엔터키 입력 시 아이템 추가 : enterKeyEventHandler 함수 . <== onKeyPress
    const enterKeyEventHandler = (e) => {
        if(e.key ==='Enter') {
            onButtonClick();
        }
    }



    

    //onInputChange 함수 TextField 컴포넌트에 연결
    // AddTodo 컴포넌트에는 에는 리스트가 넘어오지 않는다. 그리고 AddTodo는 상위 컴포넌트의 items에 접근할 수 있다.
    //따라서 item을 리스트에 추가하는 함수는 App 컴포넌트에 작성할 수 있다.
    //1. App 컴포넌트에 addItem 함수를 추가하고 이 함수를 AddTodo의 프로퍼티로 넘겨 AddTodo에서 사용한다.



    return (
        <Grid container style={{marginTop: 20}}>
            <Grid xs={11} md={11} item style={{paddingRight: 16}}>
                {/* onInputChange 함수 추가: 텍스트 => 변화감지 => item.title에 저장 */}
                <TextField placeholder="Add Todo here" fullWidth onChange={onInputChange} onKeyPress={enterKeyEventHandler} value={item.title}/>
            </Grid>
            <Grid xs={1} md={1} item>
                {/* onButtonClick 함수 추가 */}
                <Button  fullWidth style={{height: "100%"}} color="primary" variant="contained" onClick={onButtonClick}> 
                    +
                </Button>
            </Grid>
        </Grid>
    );
}

export default AddTodo;
Comments