簡體   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