如何从useEffect访问组件的当前状态而不使其成为依赖项?

时间:2020-02-26 22:50:16

标签: javascript state react-hooks use-effect

我有以下组件(简化了),给出注释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}/>
    );
}

问题在于,在useEffect中,我使用的是note,它不是依赖项的一部分,因此,我总是得到陈旧的数据。

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

所以我想知道如何在不依赖当前注释的情况下访问当前注释?我试图用ref替换注释,但这意味着更改注释后该组件不再更新,我宁愿不使用引用。

任何想法都可以做到这一点的最佳方法是什么?也许有一些特殊的React Hooks模式?

1 个答案:

答案 0 :(得分:2)

您无法获得当前状态,因为在移除该组件的应用程序渲染中该组件未渲染。这意味着您的效果永远不会在最后一次运行。

使用效果清理功能不是这类事情的好地方。确实应该保留该效果以清除该效果,而别无其他。

相反,应用程序中具有更改状态以关闭NoteViewer的任何逻辑也应保存注释。因此,在某些父组件(也许是NoteList之类的东西中),您将像这样保存并关闭:

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

  // other stuff...

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

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