Edm*_*lia 2 reactjs react-hooks use-effect
我有一个使用 useState 初始化状态的功能组件,然后通过输入字段更改该状态。
\n\n然后,我有一个模拟 componentWillUnmount 的 useEffect 挂钩,以便在组件卸载之前,将当前更新的状态记录到控制台。但是,会记录初始状态而不是当前状态。
\n\n这是我想要做的事情的简单表示(这不是我的实际组件):
\n\nimport React, { useEffect, useState } from \'react\';\n\nconst Input = () => {\n const [text, setText] = useState(\'aaa\');\n\n useEffect(() => {\n return () => {\n console.log(text);\n }\n }, [])\n\n const onChange = (e) => {\n setText(e.target.value);\n };\n\n return (\n <div>\n <input type="text" value={text} onChange={onChange} />\n </div>\n )\n}\n\nexport default Input;\nRun Code Online (Sandbox Code Playgroud)\n\n我将状态初始化为“初始”。然后我使用输入字段来更改状态,假设我输入“新文本”。但是,当组件卸载时,控制台将记录“初始”而不是“新文本”。
\n\n为什么会出现这种情况?如何在卸载时访问当前更新的状态?
\n\n非常感谢!
\n\n编辑:
\n\n将文本添加到 useEffect 依赖项数组并不能解决我的问题,因为在我的现实场景中,我想要做的是根据当前状态触发异步操作,并且它不会 \xe2\x80\x99t每次 \xe2\x80\x9ctext\xe2\x80\x9d 状态更改时都可以有效地执行此操作。
\n\nI\xe2\x80\x99m 正在寻找一种仅在组件卸载之前获取当前状态的方法。
\n您已经有效地记住了初始状态值,因此当组件卸载时,该值就是返回函数包含在其范围内的值。
\n\n\n\n\n\n\n清理函数会在组件从 UI 中删除之前运行,以防止内存泄漏。此外,如果一个组件渲染多次(正如通常所做的那样),则在执行下一个效果之前会清除前一个效果。在我们的示例中,这意味着每次更新时都会创建一个新的订阅。为了避免在每次更新时触发效果,请参阅下一节。
\n
为了在调用清理函数时获得最新状态,您需要将其包含text在依赖项数组中,以便更新函数。
\n\n\n如果传递一个空数组 (
\n[]),则效果内的 props 和 state 将始终具有其初始值。虽然[]作为第二个参数传递更接近熟悉的componentDidMount思维componentWillUnmount模型,但通常有更好的解决方案来避免过于频繁地重新运行效果。
这意味着返回的“清理”函数仍然只访问前一个渲染周期的状态和道具。
\n\n编辑
\n\n\n\n\n\n\n\n\n
useRef返回一个可变的 ref 对象,其.current属性\n 被初始化为传递的参数 (initialValue)。返回的对象将在组件的整个生命周期内持续存在。...
\n\n它可以方便地保留任何可变值,类似于您在类中使用实例字段的方式。
\n
使用 ref 将允许您缓存text可以在清理函数中访问的当前引用。
/编辑
\n\n成分
\n\nimport React, { useEffect, useRef, useState } from \'react\';\n\nconst Input = () => {\n const [text, setText] = useState(\'aaa\');\n\n // #1 ref to cache current text value\n const textRef = useRef(null);\n // #2 cache current text value\n textRef.current = text;\n\n useEffect(() => {\n console.log("Mounted", text);\n\n // #3 access ref to get current text value in cleanup\n return () => console.log("Unmounted", text, "textRef", textRef.current);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n console.log("current text", text);\n return () => {\n console.log("previous text", text);\n }\n }, [text])\n\n const onChange = (e) => {\n setText(e.target.value);\n };\n\n return (\n <div>\n <input type="text" value={text} onChange={onChange} />\n </div>\n )\n}\n\nexport default Input;\nRun Code Online (Sandbox Code Playgroud)\n\n通过返回的清理函数中的 console.log,您会注意到输入中的每次更改都会将先前的状态记录到控制台。
\n\n\n\n在此演示中,我记录了效果中的当前状态和清理函数中的先前状态。请注意,清理函数首先在下一个渲染周期的当前日志之前记录。
\n| 归档时间: |
|
| 查看次数: |
1753 次 |
| 最近记录: |