【问题标题】:React context api returning undefined when setting the state设置状态时反应上下文 api 返回未定义
【发布时间】:2020-02-04 22:59:30
【问题描述】:

我最近开始学习 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>
    );
}

我通过这样做将我的所有组件包装在 Provider 中的 App.js 中,而不是使用 ReachRouter 来处理路由,

<MyProvider>
    <div className="content">
        <Header/>
        <Router>
            <Home path="/"/>
        </Router>
    </div>
    <Footer />
</MyProvider>

在我的 Home.js 文件中,我在 useEffect 挂钩中进行了网络调用,该挂钩成功返回了我期望的 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 然后我的状态仅更新 featuresVendors 和 featuresListings 将是一个空数组。

【问题讨论】:

    标签: javascript reactjs react-redux react-hooks react-context


    【解决方案1】:

    当您调用useState 时,initialValue 仅设置一次。当您的 MyProvider 首次挂载时,状态会使用您的 setFeaturedListingssetFeaturedVendors 方法进行初始化,但这些不会在 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>
      );
    }
    

    【讨论】:

      猜你喜欢
      • 2020-08-20
      • 1970-01-01
      • 2019-12-24
      • 1970-01-01
      • 1970-01-01
      • 2020-08-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多