[React] CRUD - Update

박이레·2022년 11월 7일
0

React

목록 보기
6/12

 Update는 Create, Delete와는 조금 다릅니다. 수정은 두가지 경우가 있기 때문입니다.

① checkbox 수정
② title 수정

① checkbox 수정은 매우 간단합니다. 체크박스 클릭 시 item.done의 값을 변경하면 됩니다.
② title 수정이 약간 복잡한데요. 사용자가 title을 클릭하면 수정 가능한 상태로 만들고, Enter를 누르면 수정 내용을 저장하도록 하려고 합니다. 이를 위해 readOnly가 필요합니다.

사용자는 readOnly가 true인 경우 수정할 수 없고, false인 경우 수정할 수 있습니다.



Update

App Component

① editItem 함수는 수정 후 새로운 배열을 생성하여 추가합니다.

import './App.css';
import Todo from './Todo';
import React, { useState } from 'react';
import { Container, List, Paper } from '@mui/material';
import AddTodo from './AddTodo';

function App() {
  const [items, setItems] = useState([]);

  const addItem = (item) => {
    item.id = "ID-" + items.length;
    item.done = false;
    // 업데이트는 반드시 setItems로 하고 새 배열을 만들어야 한다.
    setItems([...items, item]);
    console.log("items : ", items);
  }

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

  const editItem = () => {
    setItems([...items]);
  }

  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">
      <AddTodo addItem={addItem} />
      <div className="TodoList">{todoItems}</div>
    </Container>
  </div>
}

export default App;

Todo Component

① editItem은 상위 컴포넌트인 App에서 props.editItem으로 함수를 불러옵니다.
② turnOnReadOnly는 사용자의 입력값(e)이 enter인 경우 ReadOnly 값을 true로 변경합니다.
③ editEventHandler는 사용자가 입력한 값(e.target.value)을 item.title에 저장합니다.

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

const Todo = (props) => {
  const [item, setItem] = useState(props.item);
  const [readOnly, setReadonly] = useState(true);
  const deleteItem = props.deleteItem;
  const editItem = props.editItem;

  const turnOffReadOnly = () => {
    setReadonly(false);
  }

  const turnOnReadOnly = (e) => {
    if (e.key === 'Enter') {
      setReadonly(true);
    }
  }

  const editEventHandler = (e) => {
    item.title = e.target.value;
    editItem();
  }

  const checkboxEventHandler = (e) => {
    item.done = e.target.checked;
    editItem();
  }

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

  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;


다음 글은 백엔드와 프론트엔드를 통합하는 방법에 대해 다룹니다.

💁‍♂️reference

React.js, 스프링 부트, AWS로 배우는 웹 개발 101

김다정 지음ㅣ에이콘출판ㅣ2022ㅣ도서 정보


EOD.

profile
혜화동 사는 Architect

0개의 댓글