Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在useEffect hook中,您建议取消订阅的模式是什么?_Javascript_Reactjs - Fatal编程技术网

Javascript 在useEffect hook中,您建议取消订阅的模式是什么?

Javascript 在useEffect hook中,您建议取消订阅的模式是什么?,javascript,reactjs,Javascript,Reactjs,你们中的大多数人可能已经看到了这个警告。我也是,我很清楚为什么React会在状态更新期间警告我们卸载。但我正试图找出防止内存泄漏的最佳反应模式 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and

你们中的大多数人可能已经看到了这个警告。我也是,我很清楚为什么React会在状态更新期间警告我们卸载。但我正试图找出防止内存泄漏的最佳反应模式

Warning: Can't perform a React state update on an unmounted component. 
This is a no-op, but it indicates a memory leak in your application. 
To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
在我的项目中,我使用这个布尔标志
didconcel
,让我的数据获取逻辑知道组件的状态。如果组件确实卸载了,则该标志应设置为true,这将导致在数据获取最终异步解决后,无法设置组件状态

useEffect(() => {
    let didCancel = false;

    const fetchEvents = () => {
      fetch(url, settings)
        .then(res => {
          return res.json();
        })
        .then(({ data }) => {
          if (!didCancel) {
            setEvents(data.events);
          }
        })
        .catch(err => {
          console.log(err);
          if (!didCancel) {
            setLoading(false);
          }
        });
    };

    fetchEvents();

    return () => {
      didCancel = true;
    };
  }, []);

所以即使这样做有效,我只想知道你们用什么作为模式。什么是最佳做法?在获取数据时和只更新状态时是否存在显著差异?请让我知道

我更喜欢使用
rxjs
库中的
defer

useEffect(() => {
  const subscription = defer(() =>
    fetch(url, settings).then(response => response.json())
  ).subscribe({
    next: ({ data }) => {
      setEvents(data.events);
    },
    error: () => {
      setLoading(false);
    },
    complete: () => {
      setLoading(false);
    }
  });

  return () => subscription.unsubscribe();
}, []);

如果组件关闭并且
useffect
运行返回函数,那么
fetchEvents
函数是否会出现?在杀死组件后,在fetchEvents()中是否有任何日志记录到console etc中?它只在装载时运行。是的,我看到了-如果组件在任务完成之前卸载,我要问的是与
fetchEvents()
中的异步调用有关,当然不会调用fetch事件中的处理程序?当组件在fetch完成之前卸载时,我当前唯一没有运行的是
setEvents
。然而,我确实读过关于在axios文档中使用的内容(我目前没有使用)。您对此有经验吗?是的,您的代码是更新状态(通常由于获取)的异步效果的基本模式。当然,使用async/await而不是then链会有语法上的变化。最终,您将转到为您实现异步模式的助手挂钩,在那里您只需提供承诺生成函数和“setState”代码。