web-dev-qa-db-ja.com

React useStateフックイベントハンドラーは初期状態を使用します

私はまだ反応フックに頭を悩ませていますが、ここで何が間違っているのかを確認するのに苦労しています。パネルのサイズを変更するためのコンポーネントがあります。エッジのオンマウスダウン状態の値を更新してから、この値を使用するmousemoveのイベントハンドラーがありますが、値が変更された後は更新されていないようです。

これが私のコードです:

export default memo(() => {
  const [activePoint, setActivePoint] = useState(null); // initial is null

  const handleResize = () => {
    console.log(activePoint); // is null but should be 'top|bottom|left|right'
  };

  const resizerMouseDown = (e, point) => {
    setActivePoint(point); // setting state as 'top|bottom|left|right'
    window.addEventListener('mousemove', handleResize);
    window.addEventListener('mouseup', cleanup); // removed for clarity
  };

  return (
    <div className="interfaceResizeHandler">
      {resizePoints.map(point => (
        <div
          key={ point }
          className={ `interfaceResizeHandler__resizer interfaceResizeHandler__resizer--${ point }` }
          onMouseDown={ e => resizerMouseDown(e, point) }
        />
      ))}
    </div>
  );
});

問題はhandleResize関数にあります。これはactivePointの最新バージョンを使用する必要があります。これは文字列top|left|bottom|rightになりますが、代わりにnullになります。

7
Simon Staton

UseEffectフックを利用して、activePointが変更されるたびにイベントリスナーを初期化できます。このようにして、コードでの不要な参照の使用を最小限に抑えることができます。

0
Vignesh Kesavan
  const [activePoint, setActivePoint] = useState(null); // initial is null

  const handleResize = () => {
    setActivePoint(currentActivePoint => { // call set method to get the value
       console.log(currentActivePoint);  
       return currentActivePoint;       // set the same value, so nothing will change
                                        // or a different value, depends on your use case
    });
  };

0
Derek Liang