无法在 React 中执行反应状态
Can't perform react state in React
我有问题。一直在这里浏览一些问题,但似乎对我不起作用。
我在使用 useEffect 时在我的三个页面中遇到此错误。
这是我的useEffect的代码
const UserDetailsPage = () => {
const classes = useStyles()
const [userData, setUserData] = useState({
_id: "",
name: "",
phone: "",
address: "",
birthdate: "",
gender: "",
messenger: "",
photo: "",
email: "",
})
const [open, setOpen] = useState(false)
const [loaded, setLoaded] = useState(false)
const { height, width } = useWindowDimensions()
const {
_id,
name,
phone,
address,
photo,
gender,
messenger,
birthdate,
email,
} = userData
useEffect(() => {
const user = getUser()
getUserById("/user/" + user.userId, user.token)
.then((data) => {
setUserData(data)
setLoaded(true)
})
.catch((error) => {
console.log(error)
})
}, [])
这是因为 useEffect
中的异步调用完成,然后在页面不再处于焦点后 setState
尝试。
可以通过像这样重构 useEffect
来避免:
useEffect(() => {
// created a boolean to check if the component is mounted, name is arbitrary
let mounted = true;
const user = getUser();
getUserById("/user/" + user.userId, user.token)
.then((data) => {
// only setState if mounted === true
if (mounted) {
setUserData(data);
setLoaded(true);
}
})
.catch((error) => {
console.log(error);
});
// set mounted to false on cleanup
return () => {
mounted = false;
};
}, []);
这里的不同之处在于我使用 mounted
布尔值来检查页面当前是否已安装。通过将 setState
调用包装在 if 状态中,我可以检查 setState
是否安全,从而避免错误。
缺少 getUserById
返回取消令牌以取消任何进行中的网络请求或“取消订阅”方法,您可以使用 React ref 来跟踪组件是否仍在安装,而不是入队如果组件已经卸载,则状态更新。
const isMountedRef = React.useRef(false);
useEffect(() => {
isMountedRef.current = true;
return () => isMountedRef.current = false;
}, []);
useEffect(() => {
const user = getUser();
getUserById("/user/" + user.userId, user.token)
.then((data) => {
if (isMountedRef.current) {
setUserData(data);
setLoaded(true);
}
})
.catch((error) => {
console.log(error);
});
}, []);
当您的组件在设置状态之前卸载时会发生这种情况。试试下面的代码来检查组件是否已安装。
useEffect(() => {
let isMounted = true; // add a flag to check component is mounted
getUserById("/user/" + user.userId, user.token)
.then((data) => {
if(mounted) { // set state only when component is mounted
setUserData(data)
setLoaded(true)
}
})
.catch((error) => {
console.log(error)
})
return () => { isMounted = false }; // cleanup toggles value, if unmounted
}, []);
不要在 useEffect 中使用异步任务。定义一个异步函数并在你的 useEffect 中调用。
示例:
const getSTH = async() =>{
getUserById("/user/" + user.userId, user.token)
.then((data) => {
if(mounted) { // set state only when component is mounted
setUserData(data)
setLoaded(true)
}
})
.catch((error) => {
console.log(error)
})
}
useEffect (()=>{
getSTH();
},[])
我认为这种方法会对你有所帮助。
我有问题。一直在这里浏览一些问题,但似乎对我不起作用。
我在使用 useEffect 时在我的三个页面中遇到此错误。
这是我的useEffect的代码
const UserDetailsPage = () => {
const classes = useStyles()
const [userData, setUserData] = useState({
_id: "",
name: "",
phone: "",
address: "",
birthdate: "",
gender: "",
messenger: "",
photo: "",
email: "",
})
const [open, setOpen] = useState(false)
const [loaded, setLoaded] = useState(false)
const { height, width } = useWindowDimensions()
const {
_id,
name,
phone,
address,
photo,
gender,
messenger,
birthdate,
email,
} = userData
useEffect(() => {
const user = getUser()
getUserById("/user/" + user.userId, user.token)
.then((data) => {
setUserData(data)
setLoaded(true)
})
.catch((error) => {
console.log(error)
})
}, [])
这是因为 useEffect
中的异步调用完成,然后在页面不再处于焦点后 setState
尝试。
可以通过像这样重构 useEffect
来避免:
useEffect(() => {
// created a boolean to check if the component is mounted, name is arbitrary
let mounted = true;
const user = getUser();
getUserById("/user/" + user.userId, user.token)
.then((data) => {
// only setState if mounted === true
if (mounted) {
setUserData(data);
setLoaded(true);
}
})
.catch((error) => {
console.log(error);
});
// set mounted to false on cleanup
return () => {
mounted = false;
};
}, []);
这里的不同之处在于我使用 mounted
布尔值来检查页面当前是否已安装。通过将 setState
调用包装在 if 状态中,我可以检查 setState
是否安全,从而避免错误。
缺少 getUserById
返回取消令牌以取消任何进行中的网络请求或“取消订阅”方法,您可以使用 React ref 来跟踪组件是否仍在安装,而不是入队如果组件已经卸载,则状态更新。
const isMountedRef = React.useRef(false);
useEffect(() => {
isMountedRef.current = true;
return () => isMountedRef.current = false;
}, []);
useEffect(() => {
const user = getUser();
getUserById("/user/" + user.userId, user.token)
.then((data) => {
if (isMountedRef.current) {
setUserData(data);
setLoaded(true);
}
})
.catch((error) => {
console.log(error);
});
}, []);
当您的组件在设置状态之前卸载时会发生这种情况。试试下面的代码来检查组件是否已安装。
useEffect(() => {
let isMounted = true; // add a flag to check component is mounted
getUserById("/user/" + user.userId, user.token)
.then((data) => {
if(mounted) { // set state only when component is mounted
setUserData(data)
setLoaded(true)
}
})
.catch((error) => {
console.log(error)
})
return () => { isMounted = false }; // cleanup toggles value, if unmounted
}, []);
不要在 useEffect 中使用异步任务。定义一个异步函数并在你的 useEffect 中调用。
示例:
const getSTH = async() =>{
getUserById("/user/" + user.userId, user.token)
.then((data) => {
if(mounted) { // set state only when component is mounted
setUserData(data)
setLoaded(true)
}
})
.catch((error) => {
console.log(error)
})
}
useEffect (()=>{
getSTH();
},[])
我认为这种方法会对你有所帮助。