whatisthis?

React JS - To Do List App(practice) 본문

PRACTICE/SELF

React JS - To Do List App(practice)

thisisyjin 2022. 2. 19. 11:10

To Do List App

 

- React JS 연습용

- create-react-app 사용

 

 


part1.

 

1 / 기본 틀 + 이벤트리스너 만들기

 

 

App.js

import { useState } from "react";

function App() {	
  const [toDo, setToDo] = useState("");
  const onChange = e => {
    setToDo(e.target.value);	
  };
  const onSubmit = e => {	// form 제출시
    e.preventDefault();
    if (toDo === "") {	// toDo가 공백이면 함수를 끝내버림
      return;
    }
    setToDo("");	// submit후 input의 value를 공백으로
  };
  return (
    <div>
      <form onSubmit={onSubmit}>
        <input
          onChange={onChange}
          value={toDo}
          type="text"
          placeholder="Write your to do..."
        />
        <button>Add To Do</button>
      </form>
    </div>
  );
}

export default App;

 

처음엔 onSubmit에서 input의 value를 어떻게 지우나 했는데

useState의 modifier함수인 setToDo함수를 한번 더 이용하면 되는구나! 싶었다.

 

- 함수는 무조건 재사용성 👍

 

 

toDo = "" 이렇게 비워버리면 state는 바뀌지 않는다.반드시 state는 modifier함수를 이용해야함.

 

state를 직접적으로 수정하면 절대 안된다.
state는 modifier함수를 통해서만 수정해야함.

 

 

 

2 /  toDo를 받는 배열을 만들기

 

- 이것도 역시 useState를 이용한다.

- Default값은 대신 빈 배열 []로 지정한다.

 

const [toDos, setToDos] = useState([]);

 

- 이 또한 마찬가지로 toDos.push()를 하면 되는게 아닌가? ❌❌❌ 절대 아님.

- state를 변경하려면 절대 push로 할 수 없다.

 

 

 

** 배열을 합치는 방법

배열을 합치는 방법
[1,2,3,4] 배열과 [6]배열을 합치려면?

 

1. concat()

arr1.concat(arr2)

 

2.  ... (spread operator)

...arr1, ...arr2, ...arr3 

 

 

[6, food]= [6, [1,2,3,4] ]

 

___

 

setToDos(prevArr => [toDo, ...prevArr]);

 

새로 받은 toDo를 맨 첫번째 요소로 두고, 이전 배열(toDos)을 합친다.

 

const onSubmit = e => {
  e.preventDefault();
  if (toDo === "") {
    return;
  }
  setToDo("");
  setToDos(prevArr => [toDo, ...prevArr]);  // 📌여기에 추가
};

 

참고로, onSubmit시마다 toDos 배열에 추가되어야하므로

아까 작성했던 onSubmit 함수 맨 밑에 추가한다.

 

 

 

3 / 제목(heading) 추가

 

<h1>To Do List ({toDos.length})</h1>

즉각적으로 toDos 배열의 갯수를 셀 수 있도록 추가해봄.

 

 

지금까지의 전체 코드 🔻

App.js

import { useState } from "react";

function App() {
  const [toDo, setToDo] = useState("");
  const [toDos, setToDos] = useState([]);
  const onChange = e => {
    setToDo(e.target.value);
  };
  const onSubmit = e => {
    e.preventDefault();
    if (toDo === "") {
      return;
    }
    setToDo("");
    setToDos(prevArr => [toDo, ...prevArr]);
  };
  console.log(toDos);
  return (
    <div>
      <h1>To Do List ({toDos.length})</h1>
      <form onSubmit={onSubmit}>
        <input
          onChange={onChange}
          value={toDo}
          type="text"
          placeholder="Write your to do..."
        />
        <button>Add To Do</button>
      </form>
    </div>
  );
}

export default App;

index.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);

 


part2.

 

 

 

toDos 배열의 각 요소를

하나하나의 컴포넌트로 만들려면?

 

 

{toDos.map(item => (
   <li>{item}</li>
))}
return (
    <div>
      <h1>To Do List ({toDos.length})</h1>
      <form onSubmit={onSubmit}>
        <input
          onChange={onChange}
          value={toDo}
          type="text"
          placeholder="Write your to do..."
        />
        <button>Add To Do</button>
      </form>
      <hr />
      <ul>
        {toDos.map(item => (
          <li>{item}</li>
        ))}
      </ul>
    </div>
  );

>> App.js의 return부분(jsx)에 ul>li로 추가해준다.

 

 

정상적으로 잘 동작한다.

(자동으로 리스트에 추가되고, li로 생성됨)

 

>> toDos는  useState로 구현한 state이고,

변경된 것만 새로 li로 추가되는 것임.

 

 

 

콘솔창

잘 동작하긴 하지만, 콘솔창을 보면

list의 각 child에는 key라는 속성이 주어져야한다고 나온다.

>> 각 li마다 고유한 키값을 가져야함.

 

 

map메소드를 보면  index값이 존재한다.

각 요소의 인덱스 번호를 number로 가지고있는 값이다.

 

따라서 이는 고유한 key로 사용 가능하므로

{toDos.map((item, index) => (
    <li key={index}>{item}</li>
))}

위와 같이 index를 매개변수로 추가한 후, key={index}를 해준다.

 

 

참고로 개발자도구 element창을 보면

li 안에 innertext 로 직접 들어간게 아니라 가상요소(::marker)로 들어간 걸 확인할 수 있다.

 

 


Ref. 

Free Lecture

 

 

ReactJS로 영화 웹 서비스 만들기 – 노마드 코더 Nomad Coders

React Fundamentals

nomadcoders.co

 

'PRACTICE > SELF' 카테고리의 다른 글

CSS - Flexbox prac.01  (0) 2022.02.26
React JS - Coin Tracker (project)  (0) 2022.02.19
React. React JS - Unit Converter (CSS추가)  (0) 2022.02.16
React) React JS - practice. 단위변환기 (Unit Conversion)  (0) 2022.02.15
CSS - Position prac.03  (0) 2022.02.12