繁体   English   中英

useEffect - 无法对未安装的组件执行 React 状态更新

[英]useEffect - Can't perform a React state update on an unmounted component

我正在创建一个网站,其中列出了几个空缺职位。

我想GET一旦组件坐骑的所有岗位。 因此,我使用了useEffect 我在useEffect设置状态,我认为这是导致错误的原因:

警告:无法对卸载的组件执行 React 状态更新。

我想知道如何解决此警告。 我不明白为什么我不能在useEffect设置状态

我的组件

function MyComponent({changeType}) {
    const [user, setUser] = React.useState([]);
    const [positions, setPositions] = React.useState([]);

    async function getAllPositions(){
        let response = await axios("http://www.localhost:3000/api/v1/positions");
        setPositions(response.data)
    }


    useEffect( ()=> {
        let jwt = window.localStorage.getItem('jwt')
        let result = jwtDecode(jwt)
        setUser(result)
        changeType() # It is a function passing props to the parent of "MyComponent"
        getAllPositions()
        }, [],
    )
    return(
        <div>
         Something
        </div>
    )
}

您应该检查在异步调用之后更新状态之前组件是否仍然安装

useEffect( ()=> {
       let unmounted = false
       async function getAllPositions(){
            let response = await  axios("http://www.localhost:3000/api/v1/positions");
            if(!unmounted)
                setPositions(response.data)
        }
        let jwt = window.localStorage.getItem('jwt')
        let result = jwtDecode(jwt)
        setUser(result)
        getAllPositions()
        return () => {
             unmounted = true
        }
}, [])

@Alexander Vidaurre Arroyo 的回答是正确的。 您基本上需要确保在卸载组件时不会更新状态。

我尝试本着钩子的精神稍微重写他的答案,以了解如何提取一些检查组件是否已安装以确定是否应更新状态的方法。

import React, { useCallback, useRef, useState } from 'react';

const useIsMounted = () => {
  const isMounted = useRef(false);
  useEffect(() => {
    isMounted.current = true;
    return () => isMounted.current = false;
  }, []);
  return useCallback(() => isMounted.current, []);
};

const useAsyncState = (defaultValue) => {
  const isMounted = useIsMounted();
  const [value, setRawValue] = useState(defaultValue);
  const setValue = useCallback((newValue) => {
    if (isMounted()) {
      setRawValue(newValue);
    }
  }, []);
  return [value, setValue];
};

const getAllPositions = async () => {
  const response = await axios("http://www.localhost:3000/api/v1/positions");
  return response.data;
};

function MyComponent() {
  const [user, setUser] = useAsyncState([]);
  const [positions, setPositions] = useAsyncState([]);

  useEffect(async () => {
    const jwt = window.localStorage.getItem('jwt');
    const result = jwtDecode(jwt);
    setUser(result);
    setPositions(await getAllPositions());
  }, [setPositions, setUser]);

  return(
    <div>
      Something
    </div>
  );
}

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM