React Todo List 만들기

React todo list 프로젝트 순서

  • 먼저 <form>태그를 만든다. 그 안에 input 박스와 button을 만들 것이다.
  • Todo List를 입력받을 <input type="text" value=""> 박스를 만든다.
  • <input>에서 입력한 값을 받을 변수를 useState를 이용해 만든다. const [todo,setTodo] = useState()
  • 만들어진 todo 변수를 input의 value 속성의 값으로 넣는다. <input value={todo || ''} type='text' /> (value코드 안에 ||''는 넣지 않아도 된다. 자꾸 콘솔에서 경고 문구가 나타나서 넣었다.)
  • <input> 박수 안에서 글이 쓰여지는 것을 감지해서 값이 변화되면 그 값으로 todo 변수의 값을 수정한다. 즉, onChange 이벤트리스너를 단다. <input onChange={onChange} value={todo} type="text" />
  • onChange 이벤트 리스너 함수를 만든다. const onChange = (e) => setTodo(e.target.value);
  • <button>태그를 넣는다. <button>Add todo</button>
  • input 박스에 값을 넣고 엔터치면 <form>이 활성화 되면서 화면이 다시 refresh된다. 이것을 막고, 공백 상태에서 엔터를 계속 입력해도 값이 입력되지 않도록 하고, 또한 일단 값을 넣고 엔터를 입력하면 다시 입력할 수 있도록 input 박스를 비우도록 하는 코드를 만들어야 한다. 이것을 <form>에 onSubmit 이벤트리스너를 설치해서 만든다. <form onSubmit = {onSubmit}>
  • 방금 만든 onSubmit 리스너 함수를 만들어 주자. const onSubmit = (e) => {...}
  • 입력한 todo 값을 배열로 저장 해줘야 한다. 그러기 위해서 배열 변수를 하나 만든다. const [todos, setTodos] = useState([]);
  • onSubmit()함수 안에서 todo가 들어올 때마다 todos 배열에 더해 줘야 한다. 하지만 react에서는 todos.push(todo)처럼 직접적으로 todos를 수정할 수 없다. 그래서 setTodos를 이용한다. 그리고 배열에 추가하는 방법도 spread operator를 이용할 것이다. setTodos(item => [...item, todo]);
  • 입력부분과 출력부분을 구분하기 위해 <hr /> 한번 넣어주고…
  • ※ React의 JSX에서 바닐라 자바스크립트를 넣고 싶으면 {}안에 넣으면 된다.
  • 리스트로 만들기 위해 <ul></ul>태그를 넣어준다.
  • ul 태그 안쪽에 자바스크립트로 li 태그를 자동으로 만들 것이다. map()함수를 이용한다. li에서 key 속성을 넣은 이유는 React에서 자꾸 넣으라고 해서 메세지가 떠서… todos.map((item,idx) => <li key={idx}>{item}</li>)
  • 여기까지 얼추 다 만들어졌다.
  • 그런데 삭제 버튼도 만들고 싶다면 <li> 안에 버튼을 만들어 넣으면 된다. <li key={idx}>{item}<button onClick={delBtn}>❌</button></li>
  • 버튼을 클릭하면 delBtn 함수가 실행된다. 이 함수는 todos 배열중에 하나를 삭제 하는 것인데 어떤 값인지를 특정해야만 한다. 그래서 현재 클릭한 todos의 값의 index 번호를 넘겨줄 필요가 있다. 그래서 className로 인덱스 번호를 넘겨 줄 것이다. <button className={idx} onClick={delBtn}>❌</button>
  • 이제 delBtn()함수를 만든다. 먼저 인덱스 값을 변수에 담는다. const idx = e.target.className; 그리고 이 idx와 todos의 각 배열의 값과 비교해서 같은 값이면 그 값은 제외하고 새로운 배열을 만드는 filter함수를 사용할 것이다. todos.filter((item,todoIdx)=>parseInt(idx) !== todoIdx)
  • parseInt()를 사용한 이유는 className의 타입은 string이고 todoidx는 number이기 때문이다. 이제 마지막으로 이렇게 filter로 걸러서 만들어진 새로운 배열을 setTodos()를 이용해서 변경 시켜주면 된다.

이제 모두 끝났다. 아래는 위의 설명에 대한 예제 코드이다. 이 과정은 노마드코더님의 무료 강좌 과정을 참고해서 만들었다.

todo list 코드

import {useState, useEffect} from 'react';


function App() {
  const [todo, setTodo] = useState();
  const [todos, setTodos] = useState([]);
  const onChange = (e)=> setTodo(e.target.value);

  const deleteBtn = (e) => {
    const idx = e.target.className
    setTodos(todos.filter((item, todoIndex) => { 
      return parseInt(idx) !== todoIndex
      })
    );
    };


  const onSubmit = (e)=> {
    e.preventDefault();
    if(todo===""){
      return;
    }
    setTodo("")
    setTodos(currentArray => [...currentArray, todo])
  }

  return (
    <div>
      <h1>My Todos ({todos.length}) </h1>
      <form onSubmit={onSubmit}>
        <input onChange={onChange} value={todo || ''} type="text" placeholder='Write To Do List' />
        
        <button>Add To Do</button>
      </form>
      <hr/>
      <ul>
        {todos.map((item,idx)=>{
          return <li key={idx}>{item}<button className={idx} onClick={deleteBtn}>❌</button></li>
        })}
      </ul>
    </div>
  );
}

export default App;

답글 남기기

2 + 5 =