使用常规React,可能会出现以下情况:
class NoteEditor extends React.PureComponent {
constructor() {
super();
this.state = {
noteId: 123,
};
}
componentWillUnmount() {
logger('This note has been closed: ' + this.state.noteId);
}
// ... more code to load and save note
}
在React Hooks中,我们可以这样写:
function NoteEditor {
const [noteId, setNoteId] = useState(123);
useEffect(() => {
return () => {
logger('This note has been closed: ' + noteId); // bug!!
}
}, [])
return '...';
}
从useEffect
返回的内容只会在组件卸载之前执行一次,但是状态(如上面的代码所示)将是陈旧的。
一个解决方案是将noteId
作为依赖项传递,但这样效果会在每次渲染时运行,而不是只运行一次;或者使用引用,但这很难维护。
那么,有没有推荐的模式来使用React Hook实现这一点呢?
使用常规React,可以从组件中的任何地方访问状态,但使用钩子似乎只有一些复杂的方法,每种方法都有严重的缺点,或者我只是遗漏了一些东西。
有什么建议吗?
4条答案
按热度按时间nkoocmlb1#
**使用Ref()**进行救援。
由于ref是可变的,并且在组件的生命周期内存在,因此我们可以使用它来存储每次更新的当前值,并且仍然可以通过ref的value**.current属性在useEffect的cleanup函数中访问该值。
因此,将有一个额外的useEffect()**来保持ref的值在状态改变时更新。
样本片段
感谢https://www.timveletta.com/blog/2020-07-14-accessing-react-state-in-your-component-cleanup-with-hooks/的作者。请参考此链接进行深入研究。
iibxawm42#
useState()
是useReducer()
的一种特殊形式,因此您可以用一个完整的reducer来替代它,以获得当前状态并解决闭包问题。注解编辑器
应用程序
67up9zun3#
我想给出一个答案,以防其他人遇到这个问题。如果你需要在useEffect卸载函数中使用多个值,那么确保使用正确的依赖关系是很重要的。所以,接受的答案很好,因为它只是一个依赖关系,但是开始包括更多的依赖关系,它就变得复杂了。你需要的useRef的数量超出了控制。所以,你可以做的是一个useRef,它是unmount函数本身,当你卸载组件时调用它:
0yycz8jy4#
对于ref中有多个项的情况,你可以把ref变成一个对象,然后给它添加你想要的键值: