리액트에서는 같은 레벨의 컴포넌트에서는 데이터를 주고 받는 게 불가능하다.
리액트에서는 데이터는 위에서 아래로 단방향으로 흐른다.
이벤트는 아래에서 위로 올라갈 수 있다.
같은 레벨에서 데이터를 주고 받기 위해서는 같은 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 함수를 넣어주고 일기를 적어보면 화면에 잘 나타나는 걸 볼 수 있다.
'React' 카테고리의 다른 글
[React] 배열안의 데이터 수정하기 (0) | 2022.06.11 |
---|---|
[React] 배열에 있는 데이터 삭제하기 (filter() 사용) (0) | 2022.06.11 |
[React] 배열로 리스트 사용하기 (map) (0) | 2022.06.10 |
[React] useRef로 React에서 DOM 조작하기 (0) | 2022.06.10 |
[React] useState로 사용자 입력 받기 (0) | 2022.06.10 |