Reactjs useEffect-Can';t在未安装的组件上执行React状态更新
我正在创建一个网站,列出了几个空缺职位 组件安装后,我想Reactjs useEffect-Can';t在未安装的组件上执行React状态更新,reactjs,react-hooks,Reactjs,React Hooks,我正在创建一个网站,列出了几个空缺职位 组件安装后,我想获得所有工作职位。因此,我使用了useffect。 我正在useffect中设置状态,我认为这是导致错误的原因: 警告:无法对已卸载的组件执行React状态更新 我想知道如何修复此警告。我不明白为什么我不能在useffect 我的组件 function MyComponent({changeType}) { const [user, setUser] = React.useState([]); const [position
获得所有工作职位。因此,我使用了useffect
。
我正在useffect
中设置状态,我认为这是导致错误的原因:
警告:无法对已卸载的组件执行React状态更新
我想知道如何修复此警告。我不明白为什么我不能在useffect
我的组件
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>
)
}
函数MyComponent({changeType}){
const[user,setUser]=React.useState([]);
const[positions,setPositions]=React.useState([]);
异步函数getAllPositions(){
让响应=等待axios(“http://www.localhost:3000/api/v1/positions");
设置位置(响应数据)
}
useffect(()=>{
让jwt=window.localStorage.getItem('jwt')
让结果=jwtDecode(jwt)
设置用户(结果)
changeType()#它是一个向“MyComponent”的父级传递道具的函数
getAllPositions()
}, [],
)
返回(
某物
)
}
在异步调用后更新状态之前,您应该检查组件是否仍在装载
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
}
}, [])
@亚历山大·维多尔·阿罗约的回答是正确的。您基本上需要确保在卸载组件时状态没有被更新
我试着按照hooks的精神重写他的答案,看看如何提取一些检查组件是否已安装的方法,以确定是否应该更新状态
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>
);
}
import React,{useCallback,useRef,useState}来自'React';
常量useIsMounted=()=>{
const isMounted=useRef(false);
useffect(()=>{
isMounted.current=真;
return()=>isMounted.current=false;
}, []);
返回useCallback(()=>isMounted.current,[]);
};
常量UseAncyState=(默认值)=>{
const isMounted=useIsMounted();
const[value,setRawValue]=使用状态(defaultValue);
const setValue=useCallback((newValue)=>{
如果(isMounted()){
setRawValue(新值);
}
}, []);
返回[value,setValue];
};
const getAllPositions=async()=>{
常量响应=等待axios(“http://www.localhost:3000/api/v1/positions");
返回响应数据;
};
函数MyComponent(){
const[user,setUser]=useAncyState([]);
const[positions,setPositions]=UseAncyState([]);
useffect(异步()=>{
const jwt=window.localStorage.getItem('jwt');
const result=jwtDecode(jwt);
设置用户(结果);
设置位置(等待getAllPositions());
},[setPositions,setUser]);
返回(
某物
);
}
在Axios调用返回之前,MyComponent
是否可能被其父组件卸载?我添加了函数changeType
,用于将道具传递给MyComponent
的父组件。您认为这可能是问题所在吗?您的意思是我在组件完全装入之前返回我的异步调用
?不,您的异步调用可能在组件卸载时返回。如下所示:装载->异步调用->卸载->异步调用返回->状态更新。因此正确的方法应该是:装载-->异步调用-->检查组件是否装载-->如果是-->异步调用返回-->状态更新?