React Context 在获取用户数据时创建了一个无限循环
Posted
技术标签:
【中文标题】React Context 在获取用户数据时创建了一个无限循环【英文标题】:React Context is creating an infinite loop when fetching user data 【发布时间】:2022-01-05 09:36:59 【问题描述】:我有一个 React 上下文,所以我可以保存一些数据并在我的 React-Project 中重用它。这是我正在处理的代码:
import React, useState, createContext from "react"
import apiRequest from "../axios"
import getCookie from "../Utils"
import jwt_decode from "jwt-decode"
export const UserContext = React.createContext()
export const UserProvider = (props) =>
const [value, setValue] = useState(
loading: false,
isLoggedIn: false,
userId: "",
username: ""
)
const updateData = (toUpdate) =>
setValue(...value, ...toUpdate)
const fetchUser = async (userId, key) =>
await apiRequest("get", "/user/" + userId, null, () => , (data) =>
updateData(
loading: false,
isLoggedIn: true,
userId: userId,
username: data.user.username
)
, (errMessage) =>
updateData(
loading: false
)
, key)
// load user data if access token is set
const accessToken = getCookie("access")
if (accessToken && !value.loggedIn && !value.loading)
updateData( loading: true )
const sub: userId = jwt_decode(accessToken)
fetchUser(userId, accessToken) // if I comment this out, then no infinite loop
const methods =
fetchUser,
updateData
return (
<UserContext.Provider value=[value, methods]>
props.children
</UserContext.Provider>
)
我已经评论了创建此循环的行。谁能告诉我为什么会这样?
【问题讨论】:
【参考方案1】:您需要在 useEffect 中执行 fetch 请求,以便仅在安装组件或 cookie 值更改时触发它。
试试这个;
import React, useState, createContext, useEffect from "react"
import apiRequest from "../axios"
import getCookie from "../Utils"
import jwt_decode from "jwt-decode"
export const UserContext = React.createContext()
export const UserProvider = (props) =>
const [value, setValue] = useState(
loading: false,
isLoggedIn: false,
userId: "",
username: ""
)
const updateData = (toUpdate) =>
setValue(...value, ...toUpdate)
const fetchUser = async (userId, key) =>
updateValue( loading: true );
await apiRequest("get", "/user/" + userId, null, () => , (data) =>
updateData(
loading: false,
isLoggedIn: true,
userId: userId,
username: data.user.username
)
, (errMessage) =>
updateData(loading: false)
, key)
// load user data if access token is set
const accessToken = getCookie("access")
useEffect(() =>
if (accessToken && !value.loggedIn && !value.loading)
const sub: userId = jwt_decode(accessToken)
fetchUser(userId, accessToken);
, [accessToken, value.loggedId, value.loading]);
const methods =
fetchUser,
updateData
return (
<UserContext.Provider value=[value, methods]>
props.children
</UserContext.Provider>
)
【讨论】:
哇,我仍然不知道为什么,但它有效哈哈。但是 fetchUser-Method 现在被调用了两次,为什么呢? 我已经更新了 useEffect[accessToken, value.loggedId, value.loading]
中的依赖关系。此外,fetchUser
会在组件挂载时调用,因此在第一次渲染时使用上下文时不必调用它。以上是关于React Context 在获取用户数据时创建了一个无限循环的主要内容,如果未能解决你的问题,请参考以下文章
如何获取数据并存储在 React Context API 中?
React/React Context API:使用 useEffect() 钩子时等待上下文值
React的Context对象解决props传递数据的烦恼!
(React Context 初学者)使用 react-router-dom 更改页面时,React Context 不启动