Front-end/클론코딩

[React 기본 일기장 만들기] React에서 배열 사용하기2- 데이터 추가하기

잔디🌿 2023. 8. 19. 23:49

 

코드 보기

 

 

 

리액트로 프로젝트를 할 때에는 항상 부모 자식간의 관계를 그림으로 표현해보아야 한다.

현재는 이러한 상태이다. 우리는 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;

 

출처 : 한입크기로 잘라먹는 리액트