[React] useState로 특정 길이만큼 배열 생성하다가 생긴 오류

정찬욱·2023년 2월 5일
0

React

목록 보기
1/1

원티드 프리온보딩 2월 인턴쉽 선발과제 하던 중


todo 수정버튼을 누르면 개별적으로 수정 창이 열리도록 구현하던 중이었다.

todos는 axios로 api의 응답을 불러온 배열이고

todo 데이터의 길이만큼 false값이 담긴 배열을 새 배열로 복사하고 싶어 다음과 같이 작성하였다.

//Todos.tsx

  const { todos } = useFetch();

  
  const [isEditTodo, setIsEditTodo] = useState(
    Array.from({ length: todos?.length }, () => false)
 ); //todo 데이터의 길이만큼 false가 담긴 배열 생성
 

여기서 isEditTodo 값을 확인해 보면 빈 배열로 나온다.
하지만 length를 todos?.length가 아닌 임의로 number값을 넣으면 배열이 잘 생성된다..

원인 (setState의 비동기작동때문)

todos?.length의 type은 number로 정의되어 있다.

만약 TodoList가 2개 있다고 가정하면

처음 랜더링시 todos?.length는 0으로 출력되다가 2로 또 한번 출력이 되는 걸 확인 할 수 있었다.

구글링으로 열심히 찾아본 결과 setState 함수는 비동기로 처리되기 때문이라서 이전의 결과를 출력해주는 것이 원인이었다. 그래서 복사한 배열이 계속 빈 배열로 나온 것이었다.

해결

  • useState함수 초기값을 빈 배열로 선언해준다.
// Todos.tsx

  const { todos } = useFetch();

  	//수정 전
  	const [isEditTodo, setIsEditTodo] = useState(
    	Array.from({ length: todos?.length }, () => false
    ));
    
   //수정 후 
    const [isEditTodo, setIsEditTodo] = useState<boolean[]>([]);

  • 수정버튼을 클릭하면 todo 데이터의 길이만큼 false값이 담긴 새 배열이 복사되도록 해준다.
/// TodoUtilButton.tsx

	 //수정 버튼 클릭 함수
	const editHandler = (event: MouseEvent<HTMLButtonElement>) => { 
       
       //todo의 길이만큼 false값이 담긴 새 배열 복사
      const todosEditBooleanArray = Array.from(
        { length: todos.length },
        () => false
      ); 
      setIsEditTodo(todosEditBooleanArray); //fasle값이 담긴 새 배열을 setState 함수에 넣어준다.
      
      //배열 복사
      let newIsEditTodo = [...isEditTodo];
      
      if (isEditTodo[index] === false) {
        newIsEditTodo[index] = true;
        setIsEditTodo([newIsEditTodo]);
      }
  };

결과 화면


profile
방문해주셔서 감사합니다.

0개의 댓글