簡體   English   中英

設置狀態時React上下文api返回未定義

[英]React context api returning undefined when setting the state

我最近開始學習反應,我正在使用上下文 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中的所有組件包裝在 Provider 中,一邊不使用 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 將是一個空數組。

當您調用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>
  );
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM