state와 setState의 동작원리

박지원 ·2024년 4월 3일
0
post-thumbnail

State의 리렌더링

리엑트가 리렌더하는 방식

setState는 비동기로 작동함.
(만약 동기로 작동하면 변경될 때마다 바로바로 리렌더링 되니까 비효율적)

따라서 임시저장소에 변경내용을 저장해뒀다가 코드를 끝까지 읽고 한번에 렌더링.

예시로 3개의 input을 모두 입력해야지 버튼이 활성화되는 코드를 짜보자.

export default function BoardWrite() {
  const [isActive, setIsActive] = useState(false);

  const [writer, setWriter] = useState();
  const [title, setTitle] = useState();
  const [contents, setContents] = useState();

  const onClickSubmit = async () => {
    const result = await 나의함수({
      variables: {
        writer: writer,
        title: title,
        contents: contents,
      },
    });
    console.log(result);
  };

  const onChangeWriter = (e) => {
    setWriter(e.target.value);
    if(writer&&title&&contents){
      setIsActive(true)
    }
  };
  const onChangeTitle = (e) => {
    setTitle(e.target.value);
    if(writer&&title&&contents){
      setIsActive(true)
    }
  };
  const onChangeContents = (e) => {
    setContents(e.target.value);
    if(writer&&title&&contents){
      setIsActive(true)
    }
  };
  return <BoardWriteUI 
  			onClickSubmit={onClickSubmit} 
            onChangeWriter={onChangeWriter} 
            onChangeTitle={onChangeTitle} 		
            onChangeContents={onChangeContents} 
            isActive={isActive} />;
}

이렇게 코드를 작성했을 때의 문제점

한글자씩 입력했을 때, 원했던대로 버튼 활성화가 되지 않음.

이유는 현재 마지막에 입력한 한글자 input은 아직 임시저장공간에 있고, 실제로 state가 변한 것이 아니기 때문

따라서 한글자를 더 입력하면 해결할 수 있다.

근데 과연 이게 진짜 해결 방법일까??

위 코드에서 만약 마지막에 내용을 한글자 a만 입력했다면, onChangeContents의 e.target.value는 a가 들어갔을 것이다. 하지만 contents라는 state는 여전히 비어있을 것임.

그렇다면 이걸 해결할 수 있는 가장 좋은 방법은 입력되었는지 확인하는 아래와 같은 코드를

if(writer&&title&&contents){
      setIsActive(true)
    }

e.target.value로 바꾸면 되는 것임.

export default function BoardWrite() {
  const [isActive, setIsActive] = useState(false);

  const [writer, setWriter] = useState();
  const [title, setTitle] = useState();
  const [contents, setContents] = useState();

  const onClickSubmit = async () => {
    const result = await 나의함수({
      variables: {
        writer: writer,
        title: title,
        contents: contents,
      },
    });
    console.log(result);
  };

  const onChangeWriter = (e) => {
    setWriter(e.target.value);
    if(e.target.value&&title&&contents){
      setIsActive(true)
    }
  };
  const onChangeTitle = (e) => {
    setTitle(e.target.value);
    if(writer&&e.target.value&&contents){
      setIsActive(true)
    }
  };
  const onChangeContents = (e) => {
    setContents(e.target.value);
    if(writer&&title&&e.target.value){
      setIsActive(true)
    }
  };
  return <BoardWriteUI 
  			onClickSubmit={onClickSubmit} 
            onChangeWriter={onChangeWriter} 
            onChangeTitle={onChangeTitle} 		
            onChangeContents={onChangeContents} 
            isActive={isActive} />;
}

(틀린 그림 찾기..)
해결 완료.

이것보다 더 효율적인 방법도 있을 것임.
그건 나중에 포스팅으로 돌아오겠음.

profile
배움이 즐거운 개발자

0개의 댓글