使用初始状态反应useState钩子事件处理程序

问题描述 投票:0回答:1

我仍然围绕着反应钩,但努力想看看我在这里做错了什么。我有一个用于调整面板大小的组件,onmousedown的一个边缘我更新了一个状态值然后有一个使用这个值的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

javascript reactjs ecmascript-6 react-hooks
1个回答
4
投票

useRef to read future value

目前,您的问题是您正在阅读过去的值。当你定义handleResize它属于那个渲染时,因此,当你重新渲染时,事件监听器没有任何反应,所以它仍然从它的渲染中读取旧值。

要解决这个问题,你应该使用useRef的ref,你会不断更新,以便你可以读取当前值。

Example (link to jsfiddle):

  const [activePoint, _setActivePoint] = React.useState(null);

  // define a ref
  const activePointRef = React.useRef(activePoint);

  // in place of original `setActivePoint`
  const setActivePoint = x => {
    activePointRef.current = x; // keep updated
    _setActivePoint(x);
  };

  const handleResize = () => {
    // now when reading `activePointRef.current` you'll
    // have access to the current state
    console.log(activePointRef.current);
  };

  const resizerMouseDown = /* still the same */;

  return /* return is still the same */
© www.soinside.com 2019 - 2024. All rights reserved.