我最近开始学习 React,并使用 context api 来存储我的全局状态。
在 MyProvider.js 文件中,我定义了我的提供程序,它仅存储 2 个 json obj 数组
import {MyContext} from "./MyContext";
import React, {useState} from "react";
export const MyProvider = (props) => {
const intialState = {
featuredListings: [],
setFeaturedListings: (val) => setState({...state, featuredListings: val}),
featuredVendors: [],
setFeaturedVendors: (val) => setState({...state, featuredVendors: val})
}
const [state, setState] = useState(intialState)
return (
<MyContext.Provider
value={state}
>
{props.children}
</MyContext.Provider>
);
}
我通过这样做将所有组件包装在提供程序的 App.js 中,而不使用 ReachRouter 来处理路由,
<MyProvider>
<div className="content">
<Header/>
<Router>
<Home path="/"/>
</Router>
</div>
<Footer />
</MyProvider>
在我的 Home.js 文件中,我在 useEffect Hook 中进行了一次网络调用,该调用成功返回了我期望的 json,并使用该 json 响应更新了上下文的状态,以便它可以全局可见。
我的代码是
export const Home = () => {
let state = useContext(MyContext)
async function apiCalls() {
const featuredVendors = await getFeaturedVendors()
console.log("featuredVendors - ", featuredVendors) // the correct response is returned
state.setFeaturedVendors(featuredVendors)
const featuredListings = await getFeaturedListing()
console.log("featuredListings - ", featuredListings) // the correct response is returned
state.setFeaturedListings(featuredListings)
}
useEffect(() => {
apiCalls()
}, []);
return (
<div>
{console.log(state.featuredVendors)} // empty array
{console.log(state.featuredListings)} // contains correct values
</div>
)
}
]
为了消除任何歧义,我的上下文是在一个名为 MyContext.js 的单独文件中创建的 我像这样创建上下文
export const MyContext = React.createContext()
为什么当我设置时,state.featuredVendors没有更新?
我注意到的另一件奇怪的事情是,如果我重新排列调用的顺序,即调用 getFeaturedListing 首先是getFeaturedVendors,然后我的状态仅更新featuredVendors 和featuredListings 将是一个空数组。
最佳答案
当您调用useState
时,initialValue仅设置一次。首次安装 MyProvider 时,会使用 setFeaturedListings
和 setFeaturedVendors
方法初始化状态,但只要 state
的值发生变化,这些状态就不会更新。因此,当您传播值时,state
的值将始终是其初始值。
setState
也可以使用始终接收当前值作为参数的函数来调用,因此您可以重写这些方法来传播该值,如下所示:
const intialState = {
featuredListings: [],
setFeaturedListings: (val) => setState(state => ({...state, featuredListings: val})),
featuredVendors: [],
setFeaturedVendors: (val) => setState(state => ({...state, featuredVendors: val}))
}
或者,您也可以将这些功能完全移出您所在的州。
export const MyProvider = (props) => {
const intialState = {
featuredListings: [],
featuredVendors: [],
}
const [state, setState] = useState(intialState)
return (
<MyContext.Provider
value={{
...state,
setFeaturedListings: (val) => setState({...state, featuredListings: val}),
setFeaturedVendors: (val) => setState({...state, featuredVendors: val})
}}
>
{props.children}
</MyContext.Provider>
);
}
关于javascript - 设置状态时,React context api 返回未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60066770/