감정일기를 만들며 배우는 리액트(React) [4] - React 일기장 만들기(Create, Read)

강준호·2024년 1월 22일

리액트

목록 보기
4/18

React 에서 사용자 Input 처리하기

useState?

  • useState는 [state, state 를 변경하기 위한 함수] 로 구성된다.
const [fooBar, setFooBar] = useState()
 const [user, setUser] = useState({
    name: "강준호",
    age: 26,
    school: "숭실대학교",
  });
<input
          name="author"
          value={state.author}
          onChange={(e) => {
            setState({
              author: e.target.value,
              content: state.content,
            });
          }}
        />

이걸 스프레드를 이용하면 더 편하게

        <input
          name="author"
          value={state.author}
          onChange={(e) => {
            setState({
              ...state,//원래있던걸 먼저!
              author: e.target.value,
            });
          }}
        />

DiaryEditor 코드

import { useState } from "react";
const DiaryEditor = () => {
  const [state, setState] = useState({
    author: "",
    content: "",
    emotion: 1,
  });

  const handleChangeState = (e) => {
    //이벤트 함수 합치기
    setState({
      ...state,
      [e.target.name]: e.target.value, //컨텐츠를 바뀐값으로
    });
  };

  const handleSubmit = () => {
    console.log(state);
    alert("저장 성공!");
  };

  return (
    <div className="DiaryEditor">
      <h2>오늘의 일기</h2>
      <div>
        <input
          name="author"
          value={state.author}
          onChange={handleChangeState}
          placeholder="작성자"
          type="text"
        />
      </div>
      <div>
        <textarea
          name="content"
          value={state.content}
          onChange={handleChangeState}
          placeholder="일기"
          type="text"
        />
      </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>
      <div>
        <button onClick={handleSubmit}>일기 저장하기</button>
      </div>
    </div>
  );
};
export default DiaryEditor;

React 에서 DOM 조작하기

useRef?

  • state 처럼 컴포넌트 re-render 사이에 값들이 보존은 되지만, state 와 달리 ref 자체의 값 변화에 의해 re-render 은 발생시키지 않는 것이 바로 ref 이다

  • html 돔(input 태그 등)에 접근할 수 있는.

Focus 주기(깜빡깜빡)

  • alert 대신 사용
  • useRef
import { useState, useRef } from "react";
const DiaryEditor = () => {
  const authorInput = useRef();
  const contentInput = useRef();
  
  .
  .
  .
  
  
  
const handleSubmit = () => {
    if (state.author.length < 1) {
      authorInput.current.focus();
      return;
    }
    if (state.content.length < 5) {
      contentInput.current.focus();
      return;
    }

React 배열 사용하기

map 사용 & key prop

  <div>
        {diaryList.map((it) => (
          <DiaryItem key={`diaryitem_${it.id}`} {...it} />
        ))}
      </div>
  • map 으로 div 에 아이템 하나씩 해서 DiaryItem 으로 넘겨줌

  • 리스트에 있는 요소들은 키 프롬이 있어야한다!

자식 아이템의 최상위 태그에 id(추천) or (순회하는 idx) 를 넣기

defaultProps

  • undefined 방지하기 위한 기본값
DiaryList.defaultProps = {
  diaryList: [],
};


컴포넌트 & 데이터 구조

  • React 는 단방향 전달밖에 안돼.
  • 이벤트는 위쪽으로, 데이터는 아래쪽으로
  • 일기 작성인 DiaryEditor 의 setData(create) 로 상위 을 바꿔. => 스테이트 끌어올리기

  • 새로운 data 는 아래에 있는 로 보내서 렌더링


새로운 데이터 Create

  • diaryList 에서 data를 사용함으로 data가 바뀌면 List도 바뀌어

App.js

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]);
  };

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

리액트 참고 블로그

https://velog.io/@jaychang99/React-%EC%9D%98-useState-%EB%BF%8C%EC%8B%9C%EA%B8%B0

0개의 댓글