useCallback onChange始终显示以前的值

时间:2020-08-08 04:35:20

标签: reactjs react-hooks

我有30个输入

我想自动/手动触发对文本更改的httprequests

但以某种方式useCallback打印以前的值

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

Edit dank-sun-h68kk

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

Edit dank-sun-h68kk

2 个答案:

答案 0 :(得分:1)

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

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

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

setState函数用于更新状态。它接受一个新的 状态值,并重新渲染组件。

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

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

编辑Demo

答案 1 :(得分:0)

Edit ecstatic-tharp-6joi6

已更改

  <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