[React]React에서 배열 사용하기 - 데이터 추가

Hyoyoung Kim·2022년 8월 20일
0

React TIL

목록 보기
26/40

🎃 상태(state) 끌어올리기

상태 끌어올리기는 자식 컴포넌트에서 어떤 부모 컴포넌트로 데이터를 이동해서,
거기서 사용하거나 또는 다른 자식 컴포넌트로 데이터를 전달하는 것

✔ 데이터는 위에서 아래로밖에 전달하지 못한다는 규칙이 있다.
(단방향 데이터 흐름 : React는 단반향으로만 데이터가 흐른다.)

✔ 반대로, 이벤트는 아래에서 위로 흐른다.(역방향 이벤트 흐름)

✔ DiaryEditor 컴포넌트에서 작성한 일기를 DiaryList 컴포넌트에 추가를 해주어야 한다.
(DiaryEditor 컴포넌트에서 생성된 데이터를 DiaryList 컴포넌트에서 필요로 한다.)

✔ DiaryEditor컴포넌트와 DiaryList컴포넌트는 형제 컴포넌트이다.

✔ 둘은 형제 컴포넌트이기 때문에 직접적으로 데이터를 넘겨줄 수 없다.

✔ 그래서 둘의 부모인 App컴포넌트를 통해서 데이터를 넘겨주어야 한다. 이것을 상태 끌어올리기라고 한다.

✔ DiaryEditor는 생성된 데이터를 상태 끌어올리기 해서 부모인 App 컴포넌트에 넘겨줘야 한다.

상태끌어올리기, 단방향 데이터 흐름, 역방향 이벤트 흐름을 사용하여 코드 작성

😎 일기를 작성하면 일기 리스트에 작성된 일기가 추가되는 것을 구현해보자!

App컴포넌트

import logo from './logo.svg';
import { useRef,  useState} from 'react';
import './App.css';
import DiaryEditor from './DiaryEditor';
import DiaryList from './DiaryList';


function App() {

//전역적으로 가장 위에서 데이터를 관리할 state
const [data, setData]= useState([]);
// 초기값은 일기 데이터를 배열을 저장할 것이기 떄문에 초기값을 빈배열로 둔다.

//일기 데이터로 추가되어야 하는 것에 id도 있다. 
const dataId = useRef(0)
//처음에는 0번 인덱스부터 시작한다. 

//App 컴포넌트에서 일기배열(data)에 새로운 일기를 추가하는 함수 작성
 const onCreate =(author,content, emotion)=> {
  const create_date = new Date().getTime()
  //새로운 일기 데이터로 추가되어야 하는 것(newItem )
  const newItem = {
    author,
    content,
    emotion,
    create_date,
    id : dataId.current
    //dataId.current의 현재 값은 0이라는 값을 가지고 있다. 
  }
  //dateId가 지금 0번을 썼기 때문에 다음 일기 데이터의 id는 1이 추가된 값을 가져야 한다.
  dataId.current +=1
  // setData갱신함수를 사용하여 원래 있던 일기 데이터(...data)에 새로운 일기데이터(newItem)를 추가한다. 
  // 그리고 새로 만들어진 일기 데이터를 일기 리스트에서 제일 윗쪽에 배치하고 싶다. 
  //그래서 새로운 일기데이터 다음으로 전의 일기 데이터가 나오게 배치해준다. 
  setData([newItem, ...data])
}; 

  return (
    <div className="App">
      <DiaryEditor onCreate = {onCreate}/>  
      {/* 일기 데이터를 추가하는 함수(onCreate)를 DiaryEditor에 prop으로 내려준다 */}
      <DiaryList diaryList ={data}/>
      {/* DiaryList컴포넌트에 App컴포넌트가 가진 일기배열데이터의 현재값(data)만 넘겨주기만 하면 된다. */}
      {/* App컴포넌트에서 data의 stata가 바뀌면 DiaryList컴포넌트에 저절로 전달이 된다. */}
    </div>
  );
}

export default App;

DiaryEditor 컴포넌트

import React, {useRef, useState} from "react";


const DiaryEditor = ({onCreate}) =>{
  //일기 데이터를 추가하는 함수(onCreate)를 DiaryEditor에 prop으로 넣어준다.

    const contentInput = useRef()
    const authorInput = useRef();

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

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

    // 저장버튼 onclick함수
    const handleSubmit = () => {
        if(state.author.length<1){
            authorInput.current.focus()
            return
        }

        if(state.content.length<5){
            contentInput.current.focus()
            return
        }
        //handleSubmit 함수는 위의 조건을 모두 충족하면 일기를 저장한다.
        //위 조건이 충족하면 저장된 일기 데이터들을 App컴포넌트에 있는 onCreate함수의 인자로 넣어준다.
        onCreate(state.author, state.content, state.emotion)
        alert("저장성공")

        // 일기를 쓰고 저장하여 일기리스트에 출력되었으면 
        // input창과 textarea창을 초기화해줘야한다. 
        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;

결과값

0개의 댓글