React

[React] 배열을 이용해서 데이터 추가하기

Alexim 2022. 6. 11. 18:20

리액트에서는 같은 레벨의 컴포넌트에서는 데이터를 주고 받는 게 불가능하다.

리액트에서는 데이터는 위에서 아래로 단방향으로 흐른다.

이벤트는 아래에서 위로 올라갈 수 있다. 

같은 레벨에서 데이터를 주고 받기 위해서는 같은 state를 공통 부모로 끌어올려서 사용할 수 있다.

 

현재 상황

DiaryEditor와 DiaryList는 현재 같은 레벨에 있다.

DiaryEditor에서 일기를 작성하면 DiaryList에서 그걸 받아서 일기 리스트 화면에 보여주려고 한다.

 

 

이 두 컴포넌트가 데이터를 공유하려면 같은 state를 공통 부모로 삼아 prop으로 내려 받아서 공유할 수 있다.

App에서 공통 부모로 삼을 data state를 만들어주고 새로운 일기를 만들 onCreate함수를 만들었다.

onCreate는 DiaryEditor에 prop으로 보내주고 data state는 DiaryList에 prop으로 보내주었다.

import './App.css';
import DiaryEditor from "./DiaryEditor"
import DiaryList from "./DiaryList"

function App() {
  const [data, setData] = useState([]);

  const dataId = useRef(0);

  const onCreate = (author, content, emotion) => {
    const created_date = new Date().getTime();
    const newItem = {
      author,
      content,
      emotion,
      created_date,
      id: dataId.current
    }
    dataId.current += 1;
    setData([newItem, ...data]);
  }

  return (
    <div className="App">
      <DiaryEditor onCreate={onCreate} />
      <DiaryList diaryList={data} />
    </div>
  );
}

export default App;

onCreate함수에서 setData로 새로운 아이템을 원래 가지고 있는 ...data 앞에 위치시켜 화면에 나타낼때 제일 상위에 나타나도록 해주었다.

 

import { useState, useRef } from "react";

const DiaryEditor = ({ onCreate }) => {
  const authorInput = useRef();
  const contentInput = useRef();

  const [state, setState] = useState({
    author: "",
    content: "",
    emotion: 1,
  })

  const handleChangeState = (e) => {
    setState({
      ...state,
      [e.target.name]: e.target.value,
    })
  }

  const handleSubmit = () => {
    if (state.author < 1) {
      authorInput.current.focus();
      return;
    }
    if (state.content.length < 5) {
      contentInput.current.focus();
      return
    }
    onCreate(state.author, state.content, state.emotion);
    alert("저장 성공했씁니다요")
  }

  return (
    <div className="DiaryEditor">
      <h2>오늘의 일기</h2>
      <div>
        <input
          ref={authorInput}
          name="author"
          value={state.author}
          onChange={handleChangeState}
        />
      </div>
      <div>
        <textarea
          ref={contentInput}
          name="content"
          value={state.content}
          onChange={handleChangeState}
        />
      </div>
      <div>
        <span>오늘의 감정점수 : </span>
        <select
          name="emotion"
          value={state.emotion}
          onChange={handleChangeState}
        >
          <option value={1}>1</option>
          <option value={2}>2</option>
          <option value={3}>3</option>
          <option value={4}>4</option>
          <option value={5}>5</option>
        </select>
      </div>
      <button onClick={handleSubmit}>일기 저장하기</button>
    </div>
  )
}

export default DiaryEditor;

DiaryEditor 컴포넌트 - handleSubmit에 prop으로 받은 onCreate 함수를 넣어주고 일기를 적어보면 화면에 잘 나타나는 걸 볼 수 있다.