使用初始状态反应 useState 钩子事件处理程序 [英] React useState hook event handler using initial state

查看:42
本文介绍了使用初始状态反应 useState 钩子事件处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我仍然在思考 React 钩子问题,但正在努力找出我在这里做错了什么.我有一个用于调整面板大小的组件,边缘的 onmousedown 我更新状态上的值然后有一个用于 mousemove 的事件处理程序,它使用这个值,但它似乎没有值改变后更新.

这是我的代码:

导出默认备忘录(() => {const [activePoint, setActivePoint] = useState(null);//初始值为空const handleResize = () =>{控制台日志(活动点);//为空,但应该是 'top|bottom|left|right'};const resizerMouseDown = (e, point) =>{设置活动点(点);//设置状态为 'top|bottom|left|right'window.addEventListener('mousemove', handleResize);window.addEventListener('mouseup', 清理);//为清晰起见删除};返回 (<div className="interfaceResizeHandler">{resizePoints.map(point => (

resizerMouseDown(e, point) }/>))}

);});

问题出在 handleResize 函数上,这应该使用最新版本的 activePoint 这将是一个字符串 top|left|bottom|right 而是 null.

解决方案

useRef 读取未来值

目前,您的问题是您正在读取过去的值.当您定义 handleResize 时,它属于该渲染,因此,当您重新渲染时,事件侦听器没有任何反应,因此它仍然从其渲染中读取旧值.

要解决此问题,您应该通过 useRef 使用一个不断更新的引用,以便您可以读取当前值.

示例(链接到 jsfiddle):

 const [activePoint, _setActivePoint] = React.useState(null);//定义一个引用const activePointRef = React.useRef(activePoint);//代替原来的`setActivePoint`const setActivePoint = x =>{activePointRef.current = x;//保持更新_setActivePoint(x);};const handleResize = () =>{//现在在阅读 `activePointRef.current` 时,你会//可以访问当前状态控制台日志(activePointRef.current);};const resizerMouseDown =/* 还是一样 */;return/* 返回还是一样的 */

I'm still getting my head around react hooks but struggling to see what I'm doing wrong here. I have a component for resizing panels, onmousedown of an edge I update a value on state then have an event handler for mousemove which uses this value however it doesn't seem to be updating after the value has changed.

Here is my code:

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>
  );
});

The problem is with the handleResize function, this should be using the latest version of activePoint which would be a string top|left|bottom|right but instead is null.

解决方案

useRef to read future value

Currently, your issue is that you're reading a value from the past. When you define handleResize it belongs to that render, therefore, when you rerender, nothing happens to the event listener so it still reads the old value from its render.

To fix this, you should use a ref via useRef that you keep updated so that you can read the current value.

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 */

这篇关于使用初始状态反应 useState 钩子事件处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆