본문 바로가기
팀프로젝트_기록일지/React_이정환_useState,useRef

(7).이정환_react.js강의_ List에 입력 후, 추가 , 삭제 구현 초기 셋팅

by 코잼민 2025. 1. 16.

1_ ★useState 초기화를 어디에 할지와 , 구성 전략 짜보기

①. 가장 상위인 App 컴포넌트에 useState 선언, 초기화

②. List를 삭제 , 편진 , 추가 하므로, 먼저, List의 구성을 파악한 뒤 , 객체 형태로 초기값 을 선언한다.

- App.js
import { useState } from "react";
import "./App.css";
import Editor from "./components/Editor";
import Header from "./components/Header";
import List from "./components/List";

const mockData = [
  {
    id: 0,
    isDone: false,
    content: "빨래하기",
    date: new Date().getTime(),
  },
  {
    id: 1,
    isDone: false,
    content: "시발",
    date: new Date().getTime(),
  },
  {
    id: 3,
    isDone: false,
    content: "련아",
    date: new Date().getTime(),
  },
];

function App() {
  const [item, setItem] = useState(mockData);

  return (
    <div className="App">
      <Header />
      <Editor />
      <List />
    </div>
  );
}

export default App;

③. 개발자 도구 창에서 App 컴포넌트에 mockData가 잘 들어갔는지 확인

2. Editor 컴포넌트의 input에 텍스트 입력후, "추가"버튼을 눌러 item 데이터 추가시켜보기

  • 순서1_ App컴포넌트에 마는 mockData를 만드는 onCeate핸들러 구현 , Editor 컴포넌트에 전달
onCreate() : 매개인자 text , 임시 객체 데이터 초기화 , setItem()에 spread 문법으로 기존 객체 배열 데이터에 추가 하기
Editor 컴포넌트에 props 로 전달
  • 순서2_ Editor 컴포넌트에 버튼 핸들러 구현 : 매개인자의 context를 onCreateItem에 대입 작동
- Editor.js
  • 순서3_ Editor 컴포넌트에 input에 text 입력 후, 그걸 매개 전달 useState 변수 추가 , 적용 구현
- Editor.js

최종 코드 :

● App.js

import { useState } from "react";
import "./App.css";
import Editor from "./components/Editor";
import Header from "./components/Header";
import List from "./components/List";

const mockData = [
  {
    id: 0,
    isDone: false,
    content: "빨래하기",
    date: new Date().getTime(),
  },
  {
    id: 1,
    isDone: false,
    content: "시발",
    date: new Date().getTime(),
  },
  {
    id: 3,
    isDone: false,
    content: "련아",
    date: new Date().getTime(),
  },
];

function App() {
  //순서1
  const [item, setItem] = useState(mockData);

  //순서1
  const onCreateItem = (context) => {
    const newTodo = {
      id: 0,
      isDone: false,
      content: context,
      date: new Date().getTime(),
    };

    setItem([newTodo, ...item]);
  };

  return (
    <div className="App">
      <Header />
      <Editor onCreateItem={onCreateItem} />
      <List />
    </div>
  );
}

export default App;

● Editor.js

import { useState } from "react";
import "./Editor.css";

function Editor({ onCreateItem }) {
  //순서3 : input의 입력 text를 useState 변수로 하기
  const [text, setText] = useState("");

  //순서3 : input창 onChange시, 값 설정 전달,
  const onChangeInput = (event) => {
    setText(event.target.value);
  };

  //순서2_ 버튼 누를시, 추가되도록 한다
  const onClickBtn = () => {
    onCreateItem(text);
  };

  return (
    <div className="Editor">
      <input
        value={text}
        onChange={onChangeInput}
        placeholder="새로운 Todo..."
      />
      <button onClick={onClickBtn}>추가</button>
    </div>
  );
}

export default Editor;

확인 방법 : 개발자 도구 창

3_ 추가된 item과 기존의 item들의 id가 고유되지 않음 => 해결방법 : useRef

- 순서1_ App 컴포넌트에 id에 대한 useRef() 객체 초기화 : 현재 data에 length 로 저장

const idRef = useRef(mockData.length);

- 순서2_ App 컴포넌트의 item create 핸들러 수정

const onCreateItem = (constent)=>{
    const newTodo = {
        id : ++idRef.current, //추가 된다면, 하나 증감 후, id 지정
        isDone : false,
        content : content,
        date : new Date().getTiem(),
    };

    setItem([newTodo,...item]);
}

출력 결과 :

4_ 완성도를 위해 처리해야할 부분들

- 빈 텍스트 input에서 '추가'버튼 누를시에는 item 추가 X

■ 순서1_ 빈 문자열 시, onCreateItem 호출 없이 return 처리
■ 순서2_ 그리고, useRef()를 통해서, item 추가 방지 + input창에 focus() 걸리도록 하기
- Editor.js
import { useRef, useState } from "react";
import "./Editor.css";

function Editor({ onCreateItem }) {
  const [text, setText] = useState("");
  const inputRef = useRef();//■순서2

  const onChangeInput = (event) => {
    setText(event.target.value);
  };

  const onClickBtn = () => {
    if (text === "") {
      inputRef.current.focus();//■순서2
      return; //■순서1
    }

    onCreateItem(text);
  };

  return (
    <div className="Editor">
      <input
        ref={inputRef}//■순서2
        value={text}
        onChange={onChangeInput}
        placeholder="새로운 Todo..."
      />
      <button onClick={onClickBtn}>추가</button>
    </div>
  );
}

export default Editor;
-Editor.css
.Editor input:focus{
    outline : 2px solid red;
}

- item 추가 후, input 창의 텍스트를 빈값으로 처리 => 버튼 핸들러 구현부에, item 추가 후, setText() 로 빈 문자열 초기화

const onClickBtn = () => {
    if (text === "") {
      inputRef.current.focus();
      return; //■순서1
    }

    onCreateItem(text);
    setText("");
  };

- '추가' 버튼 없이, Enter를 누르면, item 추가되도록 한다. => input의 onKeyDown 프로퍼티에 핸들러 구현


const onkeyDownInput = (event)=>{
    if(event.keyCode ===13){//keyCode 프로퍼티 k 소문자임 조심
        onClickBtn();//버튼의 핸들러 
    }
}

.
.
.

<input
        ref={inputRef}
        value={text}
        onKeyDown = {onkeyDownInput}//엔터에 관한 프로퍼티인 , onKeyDown에 핸들러 등록
        onChange={onChangeInput}
        placeholder="새로운 Todo..."
      />