React - practice(Simple To Do List)(1)

두두두·2022년 10월 15일
0

React

목록 보기
7/21

To Do List

할 일을 배열에 추가

npx create-react-app react-todolist로 react-todolist앱 생성
기본준비
1. input 과 todo state를 생성하여 input의 value에 넣는다
2. setTodo로 input이 변화할 때마다 todo state의 값을 변경한다
3. todo를 추가할 button생성하고 input과 button을 form으로 묶는다

function App() {
  const [todo, setTodo] = useState("");
  const onChange = (event) => setTodo(event.target.value);

  return (
    <div>
      <form>
        <input 
          onChange={onChange} 
          value={todo} 
          type="text" 
          placeholder="Write your to do..." 
        />
        <button>Add To Do</button>
      </form>
    </div>
  );
}

form은 버튼을 클릭하여 submit 할 때마다 웹을 새로고침하는 기본 이벤트를 가지고 있으므로 event.preventDefault()를 사용하여 이를 동작하지 않도록 한다

 const onSubmit = (event) => {
    event.preventDefault();
 }
  return (
    <div>
      <form onSubmit={onSubmit}>
    	...
  	  </form>
	</div>
  );

todo의 입력값이 없을 때는 submit을 해도 아무 동작이 없도록 하고 submit후에 input의 값을 초기화한다

  const onSubmit = (event) => {
    event.preventDefault();
    if(todo === ""){
      return ;
    }
    setTodo("");
  }
  return (
    <div>
      <form onSubmit={onSubmit}>
    	...
  	  </form>
	</div>
  );

todo를 저장할 배열 state를 만든다

	const [todos, setTodos] = useState([]);

버튼을 클릭하면 todo를 todos 배열에 추가한다

state의 값을 변경할 때는 절대 state를 직접적으로 바꾸지 않는다
무조건 modifier함수를 거쳐서 바꾼다

todos.push(todo); (X)
setTodos([todo, ...todos]); (O)
setTodos((curArray) => [todo, ...curArray]); (O)

...은 전개연산자로 객체의 내용을 해당 위치에 풀어준다

버튼을 누르면 todos배열에 추가되로록 코드를 추가한 후 실행하면
잘 추가되는 것을 확인할 수 있다

function App() {
  const [todo, setTodo] = useState("");
  const [todos, setTodos] = useState([]);
  const onChange = (event) => setTodo(event.target.value);
  const onSubmit = (event) => {
    event.preventDefault();
    if(todo === ""){
      return ;
    }
    console.log([todo, ...todos]);
    setTodos((curArray) => [...curArray,todo]);
    setTodo("");
  }
  
  return (
    <div>
      <h1>My To Dos ({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>
  );
}

todos 화면에 출력

lisy.map(() => {...}) 은 list의 각각의 item에 대해 {...} 부분을 실행하여 새로운 array로 반환해 주는 함수이다
lisy.map((yap) => {...})처럼 각각의 item을 yap이라는 변수에 담아서 사용할 수 있다

Map함수를 활용하여 todos의 todo를 출력할 수 있다

<ul>
	{todos.map((todo) => (
		<li>{todo}</li>
	))}
</ul>

하지만 consol.log를 살펴보면 에러가 발생하는데

이는 li에 key를 주지 않았기 때문이다

Key는 React가 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕습니다. key는 엘리먼트에 안정적인 고유성을 부여하기 위해 배열 내부의 엘리먼트에 지정해야 합니다.

Map 공식 문서를 확인해보면 Map은 세가지의 인수를 갖는데
(현재 요소, 인덱스, map을 호출한 배열) 이다
key값은 고유해야하므로 인덱스 값을 부여하면 오류가 해결된다

<ul>
	{todos.map((todo, index) => (
		<li key={index}>{todo}</li>
	))}
</ul>


전체코드

import { useState } from "react";

function App() {
  const [todo, setTodo] = useState("");
  const [todos, setTodos] = useState([]);
  const onChange = (event) => setTodo(event.target.value);
  const onSubmit = (event) => {
    event.preventDefault();
    if(todo === ""){
      return ;
    }
    setTodos((curArray) => [todo, ...curArray]);
    setTodo("");
  }
  
  return (
    <div>
      <h1>My To Dos ({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, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
    </div>
  );
}

export default App;

0개의 댓글