调用 REST API 并将其响应存储在 Context API 中

Pun*_*ari 4 javascript reactjs react-context

我的 React 应用程序要求在 Context API 中存储 API 驱动的数据。类函数不仅仅是我们正在使用的功能组件。

我尝试将 await 与 fetch 调用一起使用,但没有成功

const App = props => {
  const { initState } = props
  return (
    <AppContextProvider  initState={initState}>
      <HoldingDetailsContainer initState={initState} />
    </AppContextProvider>
  )
}

const AppContextProvider = (props) => { 
    const { resources } = useGetResourceApi();


    const context = {
        resources 
    };
    return (
        <AppContext.Provider value={context}>
            {props.children}
        </AppContext.Provider>
    )
}
Run Code Online (Sandbox Code Playgroud)

如果我在前面使用 await,useGetResourceApi它会抛出错误“对象作为 React 子对象无效(找到:[object Promise])。如果您打算渲染子对象集合,请改用数组。”

是否可以在上下文 API 中存储 API 驱动的数据

jac*_*son 6

我看不到您的 API 调用或 HoldingDetailsContainer 的详细信息,也看不到您的导入,但下面是使用 Context API + Hooks + 函数组件通过REST API 并将其提供给组件:

// App.jsx

import React from "react";
import { APIContextProvider } from "./apiContext";
import Users from "./Users";

export default function App() {
  return (
    // wrap your app (or just components that need to consume the context)
    <APIContextProvider>
      <div className="App">
        <h1>Hello CodeSandbox</h1>
        // the Users component sits below the Provider so can consume its context
        <Users />
      </div>
    </APIContextProvider>
  );
}
Run Code Online (Sandbox Code Playgroud)

// apiContext.jsx

import React, { useContext, useState, useEffect, createContext } from "react";
import axios from "axios";

const APIContext = createContext();

export function APIContextProvider({ children }) {
  // for more complex state you might set up useReducer for Redux-like state updates
  const [users, setUsers] = useState([]);
  // useEffect is a lifecycle method for function components, run once after mount
  useEffect(() => {
    // the callback to useEffect can't be async, but you can declare async within
    async function fetchData() {
      // use the await keyword to grab the resolved promise value
      // remember: await can only be used within async functions!
      const { data } = await axios.get(
        `https://jsonplaceholder.typicode.com/users`
      );
      // update local state with the retrieved data 
      setUsers(data);
    }
    // fetchData will only run once after mount as the deps array is empty 
    fetchData();
  }, []);
  return (
    <APIContext.Provider
      // Add required values to the value prop within an object (my preference)
      value={{
        users
      }}
    >
      {children}
    </APIContext.Provider>
  );
}

// Create a hook to use the APIContext, this is a Kent C. Dodds pattern
export function useAPI() {
  const context = useContext(APIContext);
  if (context === undefined) {
    throw new Error("Context must be used within a Provider");
  }
  return context;
}
Run Code Online (Sandbox Code Playgroud)

// 用户.jsx

import React from "react";
import { useAPI } from "./apiContext";

export default function Users() {
  // Now we can grab the data we want via useAPI, which abstracts useContext()
  const { users } = useAPI();
  return (
    <ul>
      // Now we can use the data from the API in our components
      // ofc this simple example can be adapted to make further calls
      {users.map(u => (
        <li key={u.id}>{u.username}</li>
      ))}
    </ul>
  );
}
Run Code Online (Sandbox Code Playgroud)

可以在我放在一起的这个沙箱中找到上述代码的有效实时版本:https : //codesandbox.io/s/context-api-fetch-data-provider-example-0rymy


Nim*_*oda 1

请看看这个要点:https://gist.github.com/nimahkh/9c008aaf2fd2d1cc83cd98c61e54979a

我认为你必须改变你的结构,存储在上下文中,就像存储在数据库或redis缓存中一样。
另外,存储在上下文中是一个异步过程,因此您必须获取 api,然后将其存储在上下文中。

我将向您展示一个包含我的要点示例的代码

const App = () => {
    const initialState = {
        theme: {primary: 'green'}
    };

    const reducer = (state, action) => {
        switch (action.type) {
            case 'storeApi':
                return {
                    ...state,
                    store_api: action.storeApi                };

            default:
                return state;
        }
    };

    return (
        <StateProvider initialState={initialState} reducer={reducer}>
            <HoldingDetailsContainer />
        </StateProvider>
    );
}
Run Code Online (Sandbox Code Playgroud)

然后我们将把我们的请求发送到上下文中

HoldingDetailsContainer 组件

const [data,setData]=useState();

function fethcData(){
   fetchApi().then(res=>{
       const {data}=res.data;
       setData(data)  //setData is useState function
})
}

//Now i need a side effect , to store data, after storing in state 
useEffect(()=>{
    dispatch({
      type: 'storeApi',
      storeApi: {data}
    })
})
Run Code Online (Sandbox Code Playgroud)