首页 > 解决方案 > 如何从 useEffect 访问组件的当前状态而不使其成为依赖项?

问题描述

我有以下组件(简化),给定一个注释 ID,它将加载并显示它。它将加载注释useEffect,当加载不同的注释或卸载组件时,它会保存注释。

const NoteViewer = (props) => {
    const [note, setNote] = useState({ title: '', hasChanged: false });

    useEffect(() => {
        const note = loadNote(props.noteId);
        setNote(note);

        return () => {
            if (note.hasChanged) saveNote(note); // bug!!
        }
    }, [props.noteId]);

    const onNoteChange = (event) => {
        setNote({ ...note, title: event.target.value, hasChanged: true });
    }

    return (
        <input value={note.title} onChange={onNoteChange}/>
    );
}

问题是在useEffectI usenote中,它不是依赖项的一部分,所以这意味着我总是得到陈旧的数据。

但是,如果我将注释放在依赖项中,那么只要注释被修改,就会执行加载和保存代码,这不是我所需要的。

所以我想知道如何访问当前笔记而不使其成为依赖项?我试图用引用替换注释,但这意味着当注释更改时组件不再更新,我宁愿不使用引用。

知道实现这一目标的最佳方法是什么吗?也许是一些特殊的 React Hooks 模式?

标签: javascriptstatereact-hooksuse-effect

解决方案


您无法获取当前状态,因为此组件不会在移除它的应用程序呈现器上呈现。这意味着您的效果上次从未运行过。

使用效果清理功能不是处理这类事情的好地方。这真的应该保留用于清理该效果,仅此而已。

相反,您在应用程序中更改状态以关闭的任何逻辑也NoteViewer应该保存注释。因此,在某些父组件(可能是 aNoteList或其他东西)中,您可以像这样保存并关闭:

function NoteList() {
  const [viewingNoteId, setViewingNoteId] = useState(null)

  // other stuff...

  function closeNote() {
    if (note.hasChanged) saveNote(note)
    setViewingNoteId(null)
  }

  return <>{/* ... */}</>
}

推荐阅读