如何在 React 状态更新加载主屏幕时删除警告

Posted

技术标签:

【中文标题】如何在 React 状态更新加载主屏幕时删除警告【英文标题】:How to remove warning while loading Home screen on React state update 【发布时间】:2020-09-24 02:52:31 【问题描述】:

在加载主屏幕时会在控制台中记录恼人的警告。如何删除此警告,我创建了一个 const isMounted = useRef(null); 它是如何工作的,我应该在哪里使用它?

  isMounted.current = true;
  return () => 
    // executed when unmount
    isMounted.current = false;
  

警告:无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请在 useEffect 清理函数中取消所有订阅和异步任务。 在 Home(由 Context.Consumer 创建) 在路线中(在 App.js:21) 在 Switch 中(在 App.js:20) 在路由器中(由 BrowserRouter 创建) 在 BrowserRouter (在 App.js:17) 应用内

Home.js

const isMounted = useRef(null);

  useEffect(() => 
    const fetchData = async () => 
      try 
        const res = await Axios.get('http://localhost:8000/service/players');
        setPlayerList(res.data.players);
        setSearchResults(res.data.players);
        showDeleteIcon(privilege);
       catch (e) 
        console.log(e);
      
    
    fetchData();
  , []);

【问题讨论】:

【参考方案1】:

如果isMounted 引用,您可以使用第二个效果来更新值。然后,在调用setState 之前,您可以检查isMounted.current 以查看您是否仍然挂载。

const isMounted = useRef(false);

useEffect(() => 
  isMounted.current = true;
  return () => isMounted.current = false;
, []);

useEffect(() => 
  const fetchData = async () => 
    try 
      const res = await Axios.get('http://localhost:8000/service/players');
      if (isMounted.current) 
        setPlayerList(res.data.players);
        setSearchResults(res.data.players);
        showDeleteIcon(privilege);
      
     catch (e) 
      console.log(e);
    
  
  fetchData();
, []);

.current 属性正是 React refs 的工作方式。我真的不确定他们为什么这样做,但本质上这就是你获取/设置价值的方式。它与 state 不同,因为 state 更改会导致重新渲染,而 ref 更新不会。

不需要 ref 和 new 效果的更好方法可能是使用状态设置器的回调版本,因为如果组件被卸载,React 可能会避免调用你的回调:

useEffect(() => 
  const fetchData = async () => 
    try 
      const res = await Axios.get('http://localhost:8000/service/players');
      setPlayerList(() => res.data.players);
      setSearchResults(() => res.data.players);
      showDeleteIcon(() => privilege);
     catch (e) 
      console.log(e);
    
  
  fetchData();
, []);

【讨论】:

太棒了,如果你也能解释一下isMounted.current doing 是什么就更好了?

以上是关于如何在 React 状态更新加载主屏幕时删除警告的主要内容,如果未能解决你的问题,请参考以下文章

“警告:无法对未安装的组件执行 React 状态更新。” [关闭]

路由器事件在构造函数上使用时会导致错误警告:无法对未安装的组件执行 React 状态更新

如何处理 React/Flux 中的保存状态?

在父组件的状态更改中重新呈现子组件

无法使用 fetch POST 方法对未安装的组件执行 React 状态更新

反应中的全局屏幕加载器