React 中带有 useEffect 的异步上下文
Posted
技术标签:
【中文标题】React 中带有 useEffect 的异步上下文【英文标题】:asynchronous context with useEffect in React 【发布时间】:2020-05-29 06:28:50 【问题描述】:我正在尝试使用从上下文组件接收的标头值创建一个 api 请求。然而,一旦页面组件被加载,它就会抛出一个Cannot read property '_id' of null
异常。有没有办法在加载上下文后立即运行 useEffect 函数?
主要组件:
import React, useState, useEffect, useContext from "react";
import "./overview.scss";
/* COMPONENTS */;
import axios from 'axios';
import GlobalContext from '../../components/context/global';
const Overview = () =>
const [bookings, setBookings] = useState([]);
const [loaded, setLoaded] = useState(false);
const [user, setUser] = useContext(GlobalContext);
useEffect(() =>
axios
.get(`/api/v1/bookings/user/$user._id`)
.then(res => setBookings(res.data))
.catch(err => console.log(err))
.finally(() => setLoaded(true));
, [user]);
上下文组件:
import React, useState, useEffect, createContext from 'react';
import jwt from 'jsonwebtoken';
/* GLOBAL VARIABLES (CLIENT) */
export const GlobalContext = createContext();
export const GlobalProvider = props =>
/* ENVIRONMENT API URL */
const [user, setUser] = useState([]);
useEffect(() =>
const getSession = async () =>
const user = await sessionStorage.getItem('authorization');
setUser(jwt.decode(user));
getSession();
, [])
return (
<GlobalContext.Provider value=[user, setUser]>
props.children
</GlobalContext.Provider>
);
;
【问题讨论】:
【参考方案1】:这里的问题是useEffect
正在挂载上运行,而您还没有用户。你只需要防范这种情况
useEffect(() =>
if (!user) return;
// use user._id
,[user])
自然,当 Context 获取用户时,它应该强制重新渲染您的组件,并且随着依赖项发生变化,useEffect
自然应该重新运行。
【讨论】:
【参考方案2】:在渲染你 GlobalProvider 之前放一个条件,例如:
return (
user.length&&<GlobalContext.Provider value=[user, setUser]>
props.children
</GlobalContext.Provider>
);
如果用户不是数组,就使用这个
return (
user&&<GlobalContext.Provider value=[user, setUser]>
props.children
</GlobalContext.Provider>
);
【讨论】:
感谢您的回复,但不幸的是它给了我一个Cannot read property length of null
。我想异步函数还没有加载。
为什么是user.length
?看起来 user
不会是这里的数组
const [user, setUser] = useState([]); ?
@FrançoisRichard 啊,我明白了,状态的默认值具有误导性,因为它没有被用作数组(语言的使用也不会暗示它,都是单数)。此外,FWIW,您不希望在上下文中使 user
成为 useEffect
的依赖项,否则您最终会出现获取用户数据的连续循环。
是的,关于循环以上是关于React 中带有 useEffect 的异步上下文的主要内容,如果未能解决你的问题,请参考以下文章
React - 带有异步 setState 的 useEffect 导致额外的重新渲染
React UseEffect 依赖于上下文不会立即更新组件
如何在 React 的 UseEffect() 中调用异步函数?
React TypeScript 16.8 如何使 useEffect() 异步