调用 REST API 并将其响应存储在 Context API 中 [英] Call REST API and store its response in Context API
问题描述
我的 React 应用程序要求将 API 驱动的数据存储在 Context API 中.类函数不仅仅是我们使用的函数组件.
我尝试将 await 与 fetch 调用一起使用,但没有成功
const App = props =>{const { initState } = 道具返回 (<AppContextProvider initState={initState}><HoldingDetailsContainer initState={initState}/></AppContextProvider>)}const AppContextProvider = (props) =>{const { 资源 } = useGetResourceApi();常量上下文 = {资源};返回 (<AppContext.Provider value={context}>{props.children}</AppContext.Provider>)}
如果我在 useGetResourceApi
前面使用 await,那么它会抛出错误对象作为 React 子对象无效(找到:[object Promise]).如果您打算渲染子对象集合,改用数组."
是否可以在上下文 API 中存储 API 驱动的数据
我看不到您的 API 调用或 HoldingDetailsContainer 的详细信息,也看不到您的导入,但下面是一个完整的(人为的)) 使用 Context API + Hooks + 函数组件通过 REST API 获取数据并将其提供给组件的示例:
//App.jsx
从react"导入React;从./apiContext"导入 { APIContextProvider };从./Users"导入用户;导出默认函数 App() {返回 (//包装您的应用程序(或仅需要使用上下文的组件)<APIContextProvider><div className="应用程序"><h1>Hello CodeSandbox</h1>//Users 组件位于 Provider 下方,因此可以使用其上下文<用户/>
</APIContextProvider>);}
//apiContext.jsx
import React, { useContext, useState, useEffect, createContext } from "react";从axios"导入 axios;const APIContext = createContext();导出函数 APIContextProvider({ children }) {//对于更复杂的状态,你可以为类似 Redux 的状态更新设置 useReducerconst [users, setUsers] = useState([]);//useEffect 是函数组件的生命周期方法,挂载后运行一次useEffect(() => {//useEffect 的回调不能是异步的,但是你可以在里面声明异步异步函数 fetchData() {//使用await 关键字来获取解析的promise 值//记住:await 只能在异步函数中使用!const { 数据 } = 等待 axios.get(`https://jsonplaceholder.typicode.com/users`);//用检索到的数据更新本地状态设置用户(数据);}//fetchData 只会在挂载后运行一次,因为 deps 数组为空fetchData();}, []);返回 (<APIContext.Provider//将所需的值添加到对象内的 value 属性(我的偏好)价值={{用户}}>{孩子们}</APIContext.Provider>);}//创建一个钩子来使用 APIContext,这是一个 Kent C. Dodds 模式导出函数 useAPI() {const context = useContext(APIContext);如果(上下文 === 未定义){throw new Error("Context 必须在 Provider 中使用");}返回上下文;}
//Users.jsx
从react"导入React;import { useAPI } from "./apiContext";导出默认函数用户(){//现在我们可以通过 useAPI 获取我们想要的数据,它抽象了 useContext()const { 用户 } = useAPI();返回 (<ul>//现在我们可以在我们的组件中使用来自 API 的数据//ofc 这个简单的例子可以用来做进一步的调用{users.map(u => (<li key={u.id}>{u.username}</li>))});}
可以在我放在一起的这个沙箱中找到上述代码的有效实时版本:https://codesandbox.io/s/context-api-fetch-data-provider-example-0rymy
I have a requirement in my react application to store API driven data in Context API. Class functions are not there only functional components we are using.
I have tried to use await with fetch call but no success
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>
)
}
If i use await in front of useGetResourceApi
then it throws error "Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead."
Is it possible to store API driven data in context API
I can't see the details of your API call or of the HoldingDetailsContainer, and also I can't see your imports, but below is a full (contrived) example of using the Context API + Hooks + function components to fetch data via a REST API and provide it to components:
// 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>
);
}
// 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;
}
// Users.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>
);
}
A working, live version of the above code can be found in this sandbox I put together: https://codesandbox.io/s/context-api-fetch-data-provider-example-0rymy
这篇关于调用 REST API 并将其响应存储在 Context API 中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!