데이터를 추가,제거 하고 화면에 렌더링 해보자

donggae·2023년 10월 24일
0

React

목록 보기
5/8
post-thumbnail

가장 먼저 생각 해봐야 할 것이 있다. 어떤 방향으로 데이터를 주고 받을 것 인지

가장 상위의 App 그 하위에 리스트를 보여주는 DataList,
DataList를 추가 삭제할 수 있는 DataEditor 이렇게 트리 형태로 구조가 형성 되어있다.

그러나 리액트에서는 같은 레벨에 있는 컴포넌트끼리는 데이터를 주고 받지 못한다.

🔎 단방향의 리액트

같은 레벨끼리는 데이터를 주고 받을 수 없다!
그럼 어떻게 데이터를 주고 받고 추가 삭제 할 수 있어?

글로 이해를 하려고 하니 어려운 부분이 있어 그림으로 알아보자

App

DataEditorDataList의 공통 부모인 AppState로 관리를 한다.
이게 무슨 말이지?

DataList

DataList 에서는 부모인 App 에게 Data를 받아 화면에 렌더링을 해주는 역할

DataEditor

DataEditor 에서는 Data라는 State를 변경할 수 있는 setData 를 통해 변경 해주는 역할

정리를 해보자면

  1. State는 배열이며, [item1] 을 가지고 있다고 가정하자
  2. DataListData에서 받은 item1을 prop로 받아 화면에 렌더링 하고 있는 상태
  3. DataEditor에서 [item2]를 추가를 하면 setData를 통해 Data 의 값을 바꾸게 된다.
  4. 그렇게 되면 State에는 [item1, item2]가 생기게 된다.
  5. DataList에는 새로운 데이터가 prop 되고 두개의 아이템이 화면에 렌더링되게 된다.

데이터를 수정하는 EVENT는 밑에서 위로, 수정된 데이터를 전달받는 DATA는 위에서 밑으로

그럼 이제 코드를 작성해보러 가자

🔥 데이터를 추가하여 화면에 렌더링 하기

  • App.jsx
import { useState } from 'react';

function App () {
	const [data,setData] = useState([])
    
    return(
    	<div className="App">
      	<DataEditor/>
        <DataList dataList={data}/>
      </div>
    )
}

data를 받아 화면에 렌더링 될 준비가 된 DataList
위의 코드에서 data를 변경 시켜줄 setData 함수를 추가해보자

import { useState, useRef } from 'react';
import './App.css';

import DataEditor from './DataEditor';
import DataList from './DataList';

function App() {
  const subject = ['국어', '수학', '영어', '과학탐구', '사회탐구'];

  const [data, setData] = useState([]);

  const dataId = useRef(0);

  const onCreate = (name, content, score) => {
    const newItem = {
      name,
      content,
      score,
      id: dataId.current,
    };
    dataId.current += 1;
    setData([newItem, ...data]);
  };
  return (
    <div className="App">
      <div className="TitleArea">
        <h2>커리큘럼</h2>
        <ul className="SubjectLuist">
          {subject.map((it, idx) => (
            <li key={idx}>{it}</li>
          ))}
        </ul>
      </div>
      <DataEditor onCreate={onCreate} />
      <DataList dataList={data} />
    </div>
  );
}
export default App;
  • dataId - 0값을 참조하는데 newItem을 만들 때 마다 +1씩 증가
  • onCreate - DataEditor에서 호출한 함수 + 상위 컴포넌트에 새로운 데이터 전달

리액트에서는 상위 컴포넌트에서 데이터를 관리, 하위 컴포넌트에 필요한 데이터를 prop로 전달하는 패턴을 가진다.

  • DataEditor.jsx

전 장에서는 버튼을 눌렀을 때 조건을 걸고 맞지 않으면 focus되고 맞으면 state를 콘솔에 저장까지 해보았다.

const DataEditor = () => {
  const handleSubmit = () => {
    onCreate(state.name, state.content, state.score);
  };
};

handleSubmit함수를 통해 state.name, state.content, state.scoreonCreate의 전달 하게 끔 하는 역할을 한다.

  • DataList.jsx
const DataList = ({ dataList }) => {
  return (
    <div className="DataList">
      <div>
        {dataList.map((it) => (
          <DataItem key={it.id} {...it} />
        ))}
      </div>
    </div>
  );
};

dataList를 prop으로 받아 key 값은 it.id ...it을 통해 해당 요소의 속성을 DataItem에 전달

  • DataItem.jsx
const DataItem = ({id, name, content, score}) => {
	return (
    	<div className="DataItem">
        <h2>{id}. {name}</h2>
        <p>{content}</p>
        <p>{score}</p>
      </div>
    )
}
export default DataItem;

🔥 추가한 데이터, 기존 데이터 삭제 해보기

데이터를 삭제하기 위해선 해당 데이터가 고유한 값을 가지고 있어야 해당 데이터에 접근을 해서 삭제, 수정이 가능하다. 그렇기에 ID에 접근해 해당 데이터를 삭제해보자

  • App.jsx

각각의 ID에 접근하여 Data를 수정하여 setData에 반영을 해보기 위해
onDelete 함수를 prop해준다.

const onDelete = (targetId) => {
  const newDataList = data.filter((it) => it.id !== targetId);
  setData(newDataList);
};
{/* 생략 */}

<DataList onDelete={onDelete}/>

현재 상태의 data 는 추가된 Item을 모두 보여주는 상태이기에
해당 ID를 가진 Item을 제외한 상태를 다시 setData를 통해 상태를 업데이트 시켜준다.

  • DataList.jsx
const DataList = ({ dataList, onDelete }) => {
	<DataItem onDelete={onDelete}/>
}

DataItemDataList에 포함이 되어 있기에 DataList가 받은 onDelete를 다시 DataItem에게 prop

  • DataItem.jsx
const DataItem = ({ id, name, content, score, onDelete }) => {
  <button
    onClick={() => {
      console.log(id); // id가 잘 출력이 되기에
	  onDelete(id); // 해당 id 삭제
    }}
  >
    삭제하기
  </button>;
};

이렇게 추가, 삭제하는 것을 알아 보았는데 아직 갈길이 멉니다
다음에는 해당 데이터를 수정해보는 것을 배워오겠습니다.

profile
아자자자

0개의 댓글