【问题标题】:useCallback onChange always shows previous valuesuseCallback onChange 总是显示以前的值
【发布时间】:2020-11-28 09:14:03
【问题描述】:

我有 30 个输入

我想在文本更改时自动/手动触发 httprequests

但不知何故 useCallback 会打印以前的值

我想使用useCallback,因为我想在深度传递给组件时保持相同的函数引用,并避免重新渲染

    import React, { useState, useCallback } from "react";
    
    export default function App() {
      const [name, setName] = useState("tom");
      const verifyName = useCallback(() => {
        console.log(`HttpRequest for name ${name}`);
      }, [name]);
     
      return (
        <div>
          Name <input value={name} onChange={(e) => {
              setName(e.target.value);
              verifyName();
            }}
          /> 
          <button onClick={verifyName}> check name </button>

        </div>
      );
    }

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    问题出在你的事件监听器上。

    onChange={(e) => {
        setName(e.target.value);
        verifyName();
    }}
    

    当您调用verifyName(这是一个副作用)时,您已经为setName 安排了一个新名称,但此操作是异步的。正如文档所说:

    setState 函数用于更新状态。它接受一个新的 状态值并将组件的重新渲染排入队列。

    类组件接受setState 的第二个参数,这是一个更新回调,仅在状态为新之后执行。然而,功能组件不再接受这一点。 React 的方法是使用 useEffect 钩子:

    useEffect(() => {
        console.log(`Http request for name ${name}`);
    }, [name]);
    

    编辑Demo

    【讨论】:

    • 如果我将http 请求移动到useEffect,那么我将失去useCallback
    • 可以混用useCallback。顺便说一句,也将数组依赖传递给 useCallback,否则每次都会重新计算。
    • 不错的尝试,但是这种设计增加了新的用例,Http req 在页面加载时触发,并且有问题它不会在页面加载时触发
    • 你总是可以创建一个自定义钩子来忽略挂载stackoverflow.com/q/55075604/6281832的影响
    【解决方案2】:

    已更改

      <input
        value={name}
        onChange={(e) => {
          setName(e.target.value);
          verifyName();
        }}
      />
    

    收件人

      <input
        value={name}
        onChange={(e) => {
          setName(e.target.value);
          verifyName(e.target.value);
        }}
      />
    

    已更改

      const verifyName = useCallback(() => {
        console.log(`Http request for name ${name}`);
      }, [name]);
    

    收件人

      const verifyName = useCallback((nameToChange) => {
        console.log(`Http request for name ${nameToChange}`);
      }, []);
    

    解释

    1. setName 这是异步的,没有像 setState 这样的第二个参数
    2. 如果我使用useEffect,那么我会松动useCallback
    3. 现在剩下的唯一选择是将new value 传递给死useCallback verifyName func

    【讨论】:

      猜你喜欢
      • 2020-06-11
      • 2020-08-18
      • 1970-01-01
      • 1970-01-01
      • 2021-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多