[React 기본 일기장 만들기] React에서 배열 사용하기2- 데이터 추가하기
리액트로 프로젝트를 할 때에는 항상 부모 자식간의 관계를 그림으로 표현해보아야 한다.
현재는 이러한 상태이다. 우리는 DiaryEditer에서 쓴 내용을 DiaryList에 추가를 해야 한다. 리액트에서는 같은 레벨에서 데이터를 주고 받을 수 없다.
그래서 위와 같이 상위에 state를 만들고, 이를 DiaryEditer에서 수정하고 DiaryList가 가져오는 방식을 사용할 것이다.
editer 내용 저장하기
App.js에 들어가서 기존데이터를 주석처리한 후 data state를 만든다. 초기값은 빈 배열이다.
그 다음 onCreate함수를 만든다. 이 함수는 author, content, emotion을 매개변수로 받고 이를 data 배열에 추가한다.
id는 쓸 때마다 하나씩 증가해야하므로, useRef를 사용하고 , 쓸 때마다 하나씩 증가시켜준다.
그 다음 setData를 이용하여 data를 추가한다. 이 때 최근에 쓴 것이 위에 오도록 하기 위해서 ...data보다 newData가 앞에 오도록 한다.
그 다음 DiaryEditor에 들어가서 props로 onCreate를 받고,
다이어리의 마지막 저장 단계인 handleSubmit함수에서 onCreate에 state의 값을 넣는다.
그럼 이렇게 저장이 되는 것을 볼 수 있다. 하지만, 저장이 완료되었음에도 일기를 쓰는 란에 데이터가 그대로 남아있다. 이를 해결하기 위해
setState를 이용해서 각각의 칸을 비워주었다.
코드
App.js
import { useRef,useState } from 'react';
import './App.css';
import DiaryEditor from './DiaryEditor';
import DiaryList from './DiaryList';
// const dummyList = [
// {
// id : 1,
// author : "잔디",
// content : "안녕",
// emotion : 5,
// created_date : new Date().getTime(),
// },
// {
// id : 2,
// author : "풀",
// content : "안녕하이",
// emotion : 2,
// created_date : new Date().getTime(),
// },
// {
// id : 3,
// author : "리액트",
// content : "안녕안녕",
// emotion : 1,
// created_date : new Date().getTime(),
// },
// ]
const 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]);//최근 것이 먼저 오도록 하기 위해 ...data보다 앞에 쓴다.
};
return (
<div className="App">
<DiaryEditor onCreate = {onCreate}/>
<DiaryList diaryList = {data}/>
</div>
);
}
export default App;
DiaryEditer.js
import {useRef,useState} 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 = (e) =>{
console.log(state);
if(state.author.length < 1){
authorInput.current.focus();
return;
}
if(state.content.length < 5){
contentInput.current.focus();
return;
}
alert("저장성공");
onCreate(state.author,state.content,state.emotion);
SetState({
author : "",
content : "",
emotion : 1,
});
}
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>
<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>
<div>
<button onClick={handleSubmit}>일기 저장하기</button>
</div>
</div>;
};
export default DiaryEditor;
출처 : 한입크기로 잘라먹는 리액트