티스토리 뷰

반응형

 

구현해야될 부분

1. input으로 사용자가 입력한 값을 받는다.

2. 사용자가 입력한 값을 배열에 객체형태로 저장하고 투두리스트로 출력한다.

3. 삭제, 체크 기능을 구현한다.

 

 

그외에 자잘한 기능

버튼 누르면

1. input 창에 포커스

2. input 값 초기화

3. input 값이 비어있으면 배열에 추가하지 않기

 

 

useState( ) 

 

 

state로 만들어야 될 부분

- 사용자가 현재 입력한 값

- 사용자가 입력한 값을 저장할 배열 (객체 형태로 저장)

 

  const [names, setNames] = useState([
    { id: 1, text: "리액트 복습하기", checked: false },
    { id: 2, text: "개인 프로젝트 계획 짜기", checked: false },
    { id: 3, text: "타입스크립트 공부하기", checked: false },
  ]);
  const [inputText, setInputText] = useState("");

names : 투두리스트의 각 항목들을 담고 있는 배열로 'id', 'text', 'checked' 속성을 가지고 있다.

  • id : 항목의 고유한 식별자이다.  새로운 항목이 추가될 때마다 1씩 증가된다.
  • text : 투두리스트 항목에 표시될 텍스트이다.
  • checked : 체크 기능을 구현할 수 있는 boolean 값이다. true 일때 항목 텍스트에 취소선이 생성된다.

 

inputText : 사용자가 input에 현재 입력한 값이다. input의 value 속성에 'inputText' 를 바인딩하면 사용자가 입력한 값이 바로바로 inputText state에 저장된다.

 

 

 

함수

 

  const onChange = (e) => {
    setInputText(e.target.value);
  };

  
  
  const onClick = () => {
    if (inputText === "") {
      return;
    }

    setNames((prevNames) => [
      ...prevNames,
      { id: names.length + 1, text: inputText, checked: false },
    ]);
    
    setInputText("");
    inputRef.current.focus();
    console.log(names);
  };



  const onRemove = (id) => {
    const removeName = names.filter((name) => name.id !== id);
    setNames(removeName);
  };



  const handleCheckbox = (id) => {
    const checkName = names.map((name) => {
      if (name.id === id) {
        return { ...name, checked: !name.checked };
      }
      return name;
    });
    setNames(checkName);
  };



  const nameList = names.map((name) => (
    // name의 checked 값이 true일때 클래스 이름에 "checked"이 들어감
    <li key={name.id}>
      <div className={name.checked ? "checked check_list" : "check_list"}>
        <input
          type="checkbox"
          checked={name.checked}
          onChange={() => handleCheckbox(name.id)}
          name="my-checkbox"
          id="opt-in"
        ></input>
        <label for="opt-in"></label>
        {name.text}
      </div>

      <button className="delete_btn" onClick={() => onRemove(name.id)}>
        ㅡ
      </button>

      {/* <p>{name.checked ? "체크됨" : "체크안됨"}</p> */}
    </li>
  ));

onChange : input의 onChange 이벤트 핸들러에 들어가는 함수로 현재 사용자가 입력한 값이 ' setInputText ' state에 저장된다.

여기서 궁금한것.. 위에서 ' inputText ' state를 input 속성의 value에 바인딩하면 사용자가 입력한 값을 바로바로 가져올 수 있다고 했는데 그럼 onChange 함수가 왜 필요한거?

검색한 결과

일반적으로 ' input '을 사용해서 사용자의 입력값을 받을 땐 'onChange' 이벤트 핸들러와 ' value ' 속성을 함께 사용한다고 한다. 그냥 둘다 사용해야된다고 외우기 ^_^!

 

 

onClick : 추가 버튼의 onClick 이벤트 핸들러에 들어가는 함수로 사용자가 입력한 새로운 항목이 기존 ' names ' state에 객체 형태로 추가된다. 새로운 항목의 'id' 값은 현재 ' names ' 배열의 길이에 +1 하면 된다.

처음엔 id 값을 state에 따로 저장시켜서 변경했는데 함수형 업데이트를 사용하면 효율적으로 항목을 추가할 수 있다!

* 함수형 업데이트란 ?
'useState' hook에서 제공하는 기능 중 하나로, 상태(state)를 업데이트하는 방식 중 하나이다. 함수형 업데이트를 사용하면 이전 상태 값을 정확하게 가져와서 새로운 상태로 업데이트할 수 있다.
  const onClick = () => {

    setNames((prevNames) => [
      ...prevNames,
      { id: names.length + 1, text: inputText, checked: false },
    ]);

}

setNames의 인자로 들어간 prevNames는 이전 상태인 names 이다. setNames 함수가 호출되면 이전의 names 상태를 가져오고 새로운 항목을 추가하여 새로운 배열이 생성된다.

 

추가로 필요한 기능은

input창이 빈 값일때 추가 안되게 + 초기화 시키기 + 포커스 주기

 

 

 

onRemove

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG more
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함