programing

useState 훅 세터가 상태를 잘못 덮어씁니다.

starjava 2023. 3. 28. 20:32
반응형

useState 훅 세터가 상태를 잘못 덮어씁니다.

문제는 다음과 같습니다.버튼 클릭 한 번으로 두 가지 기능을 호출하려고 합니다.두 함수 모두 상태를 업데이트합니다(useState 훅 사용 중).첫 번째 함수는 값 1을 'new 1'로 올바르게 업데이트하지만, 1s(setTimeout) 후 두 번째 함수가 실행되어 값 2가 'new 2'로 변경됩니다.값 1을 다시 '1'로 설정합니다.왜 이런 일이 생기는 건가요?잘 부탁드립니다!

import React, { useState } from "react";

const Test = () => {
  const [state, setState] = useState({
    value1: "1",
    value2: "2"
  });

  const changeValue1 = () => {
    setState({ ...state, value1: "new 1" });
  };
  const changeValue2 = () => {
    setState({ ...state, value2: "new 2" });
  };

  return (
    <>
      <button
        onClick={() => {
          changeValue1();
          setTimeout(changeValue2, 1000);
        }}
      >
        CHANGE BOTH
      </button>
      <h1>{state.value1}</h1>
      <h1>{state.value2}</h1>
    </>
  );
};

export default Test;

폐쇄지옥에 온 걸 환영해이 문제가 발생하는 이유는setState라고 불리고 있습니다.state새로운 메모리 참조를 취득하지만, 그 기능은changeValue1그리고.changeValue2, 클로징을 위해 이전 이니셜을 유지합니다.state언급.

솔루션을 통해setState부터changeValue1그리고.changeValue2콜백을 사용하여 최신 상태를 가져옵니다(이전 상태를 파라미터로 함).

import React, { useState } from "react";

const Test = () => {
  const [state, setState] = useState({
    value1: "1",
    value2: "2"
  });

  const changeValue1 = () => {
    setState((prevState) => ({ ...prevState, value1: "new 1" }));
  };
  const changeValue2 = () => {
    setState((prevState) => ({ ...prevState, value2: "new 2" }));
  };

  // ...
};

이 폐쇄 문제에 대한 폭넓은 논의를 이곳저곳에서 볼 수 있습니다.

기능은 다음과 같습니다.

const changeValue1 = () => {
    setState((prevState) => ({ ...prevState, value1: "new 1" }));
};
const changeValue2 = () => {
    setState((prevState) => ({ ...prevState, value2: "new 2" }));
};

따라서 액션이 실행될 때 이전 상태를 사용하여 현재 상태의 기존 속성이 누락되지 않았는지 확인합니다.따라서 폐쇄를 관리할 필요가 없습니다.

언제changeValue2기동되어 초기 상태가 유지되어 상태가 초기 상태로 되돌아가고 나서value2속성이 작성되었습니다.

다음에changeValue2그 후에 호출되어 상태를 유지합니다.{value1: "1", value2: "new 2"},그렇게value1속성을 덮어씁니다.

이 경우 화살표 기능이 필요합니다.setState파라미터를 지정합니다.

const Test = () => {
  const [state, setState] = React.useState({
    value1: "1",
    value2: "2"
  });

  const changeValue1 = () => {
    setState(prev => ({ ...prev, value1: "new 1" }));
  };
  const changeValue2 = () => {
    setState(prev => ({ ...prev, value2: "new 2" }));
  };

  return (
    <React.Fragment>
      <button
        onClick={() => {
          changeValue1();
          setTimeout(changeValue2, 1000);
        }}
      >
        CHANGE BOTH
      </button>
      <h1>{state.value1}</h1>
      <h1>{state.value2}</h1>
    </React.Fragment>
  );
};

ReactDOM.render(<Test />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>

지금 일어나고 있는 일은 둘 다changeValue1그리고.changeValue2두 함수가 처음 렌더링될 때 다음 두 함수가 표시됩니다.

state= {
  value1: "1",
  value2: "2"
}

버튼을 클릭하면changeValue1먼저 호출되어 상태가 로 변경됩니다.{value1: "new1", value2: "2"}역시나

이제 1초 후에changeValue2이 함수는 아직 초기 상태를 표시합니다({value1; "1", value2: "2"}이 함수가 상태를 다음과 같이 갱신할 경우:

setState({ ...state, value2: "new 2" });

다음과 같이 표시됩니다.{value1; "1", value2: "new2"}.

원천

언급URL : https://stackoverflow.com/questions/58193166/usestate-hook-setter-incorrectly-overwrites-state

반응형