简体   繁体   English

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

[英]How to access current state of component from useEffect without making it a dependency?

I've got the following component (simplified) which, given a note ID, would load and display it.我有以下组件(简化),给定一个音符 ID,它将加载并显示它。 It would load the note in useEffect and, when a different note is loaded or when the component gets unmounted, it saves the note.它会在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}/>
    );
}

The issue is that within the useEffect I use note , which is not part of the dependencies so it means I always get stale data.问题是在useEffect我使用了note ,它不是依赖项的一部分,所以这意味着我总是得到陈旧的数据。

However, if I put the note in the dependencies then the loading and saving code will be executed whenever the note is modified, which is not what I need.但是,如果我将注释放在依赖项中,那么每当修改注释时都会执行加载和保存代码,这不是我需要的。

So I'm wondering how can I access the current note, without making it a dependency?所以我想知道如何访问当前笔记而不使其成为依赖项? I've tried to replace the note with a ref, but it means the component no longer updates when the note is changed, and I'd rather not use references.我尝试用 ref 替换注释,但这意味着当注释更改时组件不再更新,我宁愿不使用引用。

Any idea what would be the best way to achieve this?知道什么是实现这一目标的最佳方法吗? Maybe some special React Hooks pattern?也许是一些特殊的 React Hooks 模式?

You can't get the current state because this component does not render on the app render that removes it.您无法获取当前状态,因为此组件不会在移除它的应用程序渲染上呈现。 Which means your effect never runs that last time.这意味着您的效果永远不会像上次那样运行。

Using an effect cleanup function is not a good place for this sort of thing.使用效果清理功能不是处理这类事情的好地方。 That should really be reserved for cleaning up that effect and nothing else.这应该真正保留用于清理该效果而不是其他任何东西。

Instead, whatever logic you have in the app that changes the state to close the NoteViewer should also save the note.相反,您在应用程序中更改状态以关闭NoteViewer任何逻辑也应该保存笔记。 So in some parent component (perhaps a NoteList or something) you'd save and close like:因此,在某些父组件(可能是NoteList或其他东西)中,您可以像这样保存并关闭:

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

  // other stuff...

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在数组依赖中正确使用 useEffect 钩子。 我从 redux 商店传递了状态,但我的组件仍然无限渲染 - How to use useEffect hook properly with array dependency. I passed state from redux store and still my component renders infinitely 有没有办法只调用一次 useEffect 并且还可以访问组件的当前状态? - Is there a way to call useEffect only once and also have access to the current state of component? 如何访问另一个组件中的当前状态? - How to access a current state in another component? 如何在不重新触发 useEffect 的情况下在 useEffect 中访问 state? - How can I access state in an useEffect without re-firing the useEffect? 在 React 中,当它是 useEffect 的依赖项而不触发另一个 API 调用时,我如何将 append 值转换为功能 state? - In React how can I append values to functional state when it is a dependency of useEffect without triggering another API call? useEffect 在没有任何依赖的组件下多次调用 API - useEffect is calling API multiple time under component without any dependency 一个组件的 Redux 状态更改不会触发另一个组件中的 useEffect - Redux state change from one component not triggering useEffect in another component 使用useEffect渲染主要组件时,如何从本地存储中设置反应state? - How to set react state from local storage when rendering main component, using useEffect? 在 useEffect 中设置状态,并将该状态作为依赖项 - setting the state inside the useEffect with that state as a dependency 如何从另一个组件访问一个组件的状态 - How to access one component's state from another component
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM