【问题标题】:React custom hook doesn't update stateReact 自定义钩子不会更新状态
【发布时间】:2021-08-31 00:28:42
【问题描述】:

这里我有一个示例钩子

const useGPS = () => {
  const [gps, setGps] = useState({})

  useEffect(() => {
    setGps({ a: 1 })
  }, [])

  return [gps]
}

这很简单,但是当我在另一个组件中使用它时

const Foo = () => {
  const location = useGPS()
  
  useEffect(() => {
    console.log(location);
  }, [])

  return (
    <div>1</div>
  )
}

控制台总是第一次记录空对象。有人可以解释发生了什么,我该如何解决?对不起我的英语不好。非常感谢!

【问题讨论】:

  • 您是否从该组件中导出了 useGPS?
  • @MattLaszcz 是的,我做到了

标签: reactjs react-hooks use-effect


【解决方案1】:

GPS 的值仅在第一次 useEffect 运行后设置(在自定义挂钩内)。它最初是空的,当 useEffect(foo 组件) 运行时,会显示该空值。

该值设置成功,如果您从 Foo 组件的 useEffect 中删除 [] 数组,您可以检查这一点。 [] 表示挂载后只会运行一次,充当componentDidMount。


export default function App() {
  const location = useGPS()
  
  useEffect(() => {
    console.log(location);
  });

  return (
    <div>1</div>
  )

}

【讨论】:

  • 我必须做什么才能让 Foo useEffect 等到 useGPS useEffect setGPS 成功?
  • 自定义钩子中的 useEffect 没有什么特别之处,当您调用钩子时,它将被附加(不是最好的词,但我希望它能够理解这一点)到组件。既然是这样,那么两个 useEffects 将以相同的方式运行,它只取决于您传递的依赖数组。
  • 简而言之,您无法确保它等待。请记住,钩子应该在组件的顶层或另一个钩子内调用。您可以做的是在第二次运行时,您可以使用该值。如果您的组件更复杂,您可以将location 添加到依赖数组中,就像@Andris 所做的那样。这确保仅在位置发生变化时调用useEffect回调。
  • 我在外面看到了很多自定义钩子,我参考了其中一个(我正在练习编写自定义钩子)。他们仍然可以使用来自 useGPS 的值传递(在本例中是 {a:1}),而无需任何 useEffect 来观看它。我错过了什么吗?
  • 你能分享一个你所说的例子吗?例如,这里是代码沙盒上的一个 - codesandbox.io/s/tabs-with-react-memo-forked-zxjm3?file=/src/…。您可以更改代码并使用[] 看看它不起作用
【解决方案2】:

添加到 Tushar 的答案中,如果您想修复该行为而不让 useEffect 在每次更新时都运行(这可能会在一些更复杂的示例中导致错误),您可以将 location 添加到 useEffect 的依赖项中:

const Foo = () => {
  const location = useGPS();

  useEffect(() => {
    console.log(location);
  }, [location]);

  return <div>1</div>;

};

这样,只有在为 location 生成了新值时,效果才会运行。第一次调用 console.log 时,您仍然会看到一个空对象,但它会立即更新为生成的值。

【讨论】:

    【解决方案3】:

    const [位置] = useGPS();

    你需要析构位置状态数组

    【讨论】:

      猜你喜欢
      • 2019-10-29
      • 1970-01-01
      • 2021-08-08
      • 1970-01-01
      • 2020-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多