确保在调用函数之前设置状态反应钩子

Posted

技术标签:

【中文标题】确保在调用函数之前设置状态反应钩子【英文标题】:Make sure state is set before function is called react hooks 【发布时间】:2021-12-18 05:15:02 【问题描述】:

想象一下你有这种情况

 useEffect(() => 
    console.log('query changed');
    setSomething(1)
    getStuff();
  , [props.match.params.query])

const getStuff = async () => 
   console.log(something)

我发现在这种情况下,某些东西将始终是以前的值。因此,例如,如果您更改道具并且某物为 2,它将调用 setSomething(1),并将其放入队列中。但是,当您进入 getStuff 时,仍然是 2。如何使 setState 函数始终在调用下一个函数之前应用?

【问题讨论】:

这能回答你的问题吗? ***.com/questions/30782948/… 我知道状态回调,但是没有外部依赖的钩子不支持这些回调。我的印象是,如果你想找到 useEffect 之外的值,它会被更新,但显然那不是真的。 您需要一个单独的 useEffect 挂钩来调用 getStuff(),只要您的状态发生变化,就会运行该挂钩。然后getStuff() 将具有更新的状态。 【参考方案1】:

您的函数 getStuff 是 async 您需要使用 await,将该函数包装在另一个函数中并调用它

useEffect(() => 
    console.log('query changed');
    const getData=()=>
      setSomething(1)
      await getStuff();
    
    getData()
  , [props.match.params.query])

你看不到 useEffect 的变化,因为 useState 是 async,你需要把更多的底部放在你的控制台

console.log(something)
return (
  <div></div>
)

【讨论】:

当我这样做时,getStuff() 控制台日志仍然不正确。如果我 setSomething(1),然后调用 await getStuff,控制台日志显示 2。【参考方案2】:

问题是当您调用getStuff 时,它会访问过时的状态值。要获得实际的,您可以使用 useCallback 创建一个与更新后的状态值绑定的函数。

export default function App() 
  const [something, setSomething] = useState();
  const [query, setQuery] = useState(0);
  const getStuff = useCallback(() => 
    console.log("something", something);
  , [something]);

  useEffect(() => 
    console.log("query changed");
    setSomething(query);
    getStuff();
  , [query, getStuff]);

  console.log("query", query);

  return (
    <div className="App">
      <button
        onClick=() => 
          setQuery(Math.random());
        
      >
        Change
      </button>
    </div>
  );

它能解决你的问题吗?

你可以在这里查看https://codesandbox.io/s/naughty-lewin-rsvh5?file=/src/App.js:82-634

【讨论】:

以上是关于确保在调用函数之前设置状态反应钩子的主要内容,如果未能解决你的问题,请参考以下文章

使用React useContext hook进行分派调用后,反应状态不会更新

传递给子组件时道具未定义(反应钩子)

如何在反应中使用带有useState钩子的回调[重复]

反应:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用

如何确保更新 reactjs 状态,然后调用函数?

无效的挂钩调用。钩子只能在反应函数组件内部使用...... useEffect,redux