在功能组件中使用 REST Api 调用更新 React 上下文
Update React Context using a REST Api call in a functional component
我正在尝试使用 API 调用后端 REST API 产生的数据更新 React 应用程序的上下文。问题是我无法同步该功能。
我已经尝试过此博客 post https://medium.com/@__davidflanagan/react-hooks-context-state-and-effects-aa899d8c8014 中建议的解决方案,但它不适用于我的情况。
这是 textContext.js
的代码
import React, {useEffect, useState} from "react";
import axios from "axios";
var text = "Test";
fetch(process.env.REACT_APP_TEXT_API)
.then(res => res.json())
.then(json => {
text = json;
})
const TextContext = React.createContext(text);
export const TextProvider = TextContext.Provider;
export const TextConsumer = TextContext.Consumer;
export default TextContext
这是我尝试从上下文访问数据的功能组件
import TextProvider, {callTextApi} from "../../../../services/textService/textContext";
function Profile()
{
const text = useContext(TextProvider);
console.log(text);
const useStyles = makeStyles(theme => ({
margin: {
margin: theme.spacing(1)
}
}));
我可以看到获取请求在浏览器控制台的网络部分获取数据,但上下文没有得到更新。
我试过在 textContext.js 中这样做。
export async function callTextApi () {
await fetch(process.env.REACT_APP_TEXT_API)
.then(res => res.json())
.then(json => {
return json;
})
}
并且我试图使用 useEffect 函数在 Profile.js 中获取数据
const [text, setText] = useState(null);
useEffect(()=> {
setText (callTextApi())
},[])
这是我第一次使用 React.context 并且非常混乱。我做错了什么或遗漏了什么?
我看到的第一件事是您没有 return 在您的函数中执行承诺,这将导致将状态设置为未定义。
我在下面添加了 return 语句:
export async function callTextApi () {
return await fetch(process.env.REACT_APP_TEXT_API)
.then(res => res.json())
.then(json => {
return json;
})
}
您最后的 then-chain 也可以稍微清理一下,我很确定您可以在 return 承诺时删除异步函数中的 await 语句。将自动等待:
export async function callTextApi () {
return fetch(process.env.REACT_APP_TEXT_API)
.then(res => res.json())
.then(json => json)
}
第二步是查看您的 useEffect
挂钩。在 api 调用的承诺得到解决后,您想 setText
。所以你也必须让 useEffect
的回调函数异步。
useEffect(async ()=> {
const newText = await callTextApi();
setText (newText);
},[])
第三步,将查看如何正确使用上下文 api 和 useContext
挂钩。 useContext
挂钩将上下文作为参数,但您将 ContextProvider 作为参数传递。
const text = useContext(TextContext);
上下文和上下文提供者是 React 世界中的两个不同实体。将上下文视为您希望在应用程序中共享的状态和功能(如全局状态),并将提供者视为管理一个上下文并将此上下文状态提供给它的子组件的反应组件。
return(
<TextContext.Provider value={/* some value */}>
{children}
</TextContext.Provider>);
这是提供程序组件的 return 语句的样子,我认为您的应用程序中目前缺少这段代码。
你这里有很多问题。 fetching
并且应该通过修改 value
属性 在 Provider
内部进行更改。 useContext
接收整个 Context
对象,而不仅仅是 Provider
。检查以下内容
//Context.js
export const context = React.createContext()
现在在你的Provider
里面
import { context } from './Context'
const MyProvider = ({children}) =>{
const [data, setData] = useState(null)
useEffect(() =>{
fetchData().then(res => setData(res.data))
},[])
const { Provider } = context
return(
<Provider value={data}>
{children}
</Provider>
)
}
现在你有一个 Provider
可以获取一些 data
并将其传递到 value
道具中。要从 functional component
中使用它,请像这样使用 useContext
import { context } from './Context'
const Component = () =>{
const data = useContext(context)
return <SomeJSX />
}
记住Component
必须在MyProvider
之下
更新
- 什么是
{ children }
?
Component
声明中的所有内容都映射到 props.children
。
const App = () =>{
return(
<Button>
Title
</Button>
)
}
const Button = props =>{
const { children } = props
return(
<button className='fancy-button'>
{ children /* Title */}
</button>
)
}
像 ({ children })
一样声明它只是 const { children } = props
的快捷方式。我正在使用 children
这样你就可以像这样使用你的 Provider
<MyProvider>
<RestOfMyApp />
</MyProvider>
这里children
是RestOfMyApp
- 如何访问 Profile.js 中 Provider 的值?
使用createContext
。假设您的 Provider
的 value
属性 是 {foo: 'bar'}
const Component = () =>{
const content = useContext(context)
console.log(content) //{ foo : 'bar' }
}
- 如何像在 Provider 中那样双重声明常量?
打错了,我改成了MyProvider
从基于 class
的组件内部访问它
class Component extends React.Component{
render(){
const { Consumer } = context
return(
<Consumer>
{
context => console.log(contxt) // { foo: 'bar' }
}
</Consumer>
)
}
}
我正在尝试使用 API 调用后端 REST API 产生的数据更新 React 应用程序的上下文。问题是我无法同步该功能。
我已经尝试过此博客 post https://medium.com/@__davidflanagan/react-hooks-context-state-and-effects-aa899d8c8014 中建议的解决方案,但它不适用于我的情况。
这是 textContext.js
的代码import React, {useEffect, useState} from "react";
import axios from "axios";
var text = "Test";
fetch(process.env.REACT_APP_TEXT_API)
.then(res => res.json())
.then(json => {
text = json;
})
const TextContext = React.createContext(text);
export const TextProvider = TextContext.Provider;
export const TextConsumer = TextContext.Consumer;
export default TextContext
这是我尝试从上下文访问数据的功能组件
import TextProvider, {callTextApi} from "../../../../services/textService/textContext";
function Profile()
{
const text = useContext(TextProvider);
console.log(text);
const useStyles = makeStyles(theme => ({
margin: {
margin: theme.spacing(1)
}
}));
我可以看到获取请求在浏览器控制台的网络部分获取数据,但上下文没有得到更新。
我试过在 textContext.js 中这样做。
export async function callTextApi () {
await fetch(process.env.REACT_APP_TEXT_API)
.then(res => res.json())
.then(json => {
return json;
})
}
并且我试图使用 useEffect 函数在 Profile.js 中获取数据
const [text, setText] = useState(null);
useEffect(()=> {
setText (callTextApi())
},[])
这是我第一次使用 React.context 并且非常混乱。我做错了什么或遗漏了什么?
我看到的第一件事是您没有 return 在您的函数中执行承诺,这将导致将状态设置为未定义。
我在下面添加了 return 语句:
export async function callTextApi () {
return await fetch(process.env.REACT_APP_TEXT_API)
.then(res => res.json())
.then(json => {
return json;
})
}
您最后的 then-chain 也可以稍微清理一下,我很确定您可以在 return 承诺时删除异步函数中的 await 语句。将自动等待:
export async function callTextApi () {
return fetch(process.env.REACT_APP_TEXT_API)
.then(res => res.json())
.then(json => json)
}
第二步是查看您的 useEffect
挂钩。在 api 调用的承诺得到解决后,您想 setText
。所以你也必须让 useEffect
的回调函数异步。
useEffect(async ()=> {
const newText = await callTextApi();
setText (newText);
},[])
第三步,将查看如何正确使用上下文 api 和 useContext
挂钩。 useContext
挂钩将上下文作为参数,但您将 ContextProvider 作为参数传递。
const text = useContext(TextContext);
上下文和上下文提供者是 React 世界中的两个不同实体。将上下文视为您希望在应用程序中共享的状态和功能(如全局状态),并将提供者视为管理一个上下文并将此上下文状态提供给它的子组件的反应组件。
return(
<TextContext.Provider value={/* some value */}>
{children}
</TextContext.Provider>);
这是提供程序组件的 return 语句的样子,我认为您的应用程序中目前缺少这段代码。
你这里有很多问题。 fetching
并且应该通过修改 value
属性 在 Provider
内部进行更改。 useContext
接收整个 Context
对象,而不仅仅是 Provider
。检查以下内容
//Context.js
export const context = React.createContext()
现在在你的Provider
import { context } from './Context'
const MyProvider = ({children}) =>{
const [data, setData] = useState(null)
useEffect(() =>{
fetchData().then(res => setData(res.data))
},[])
const { Provider } = context
return(
<Provider value={data}>
{children}
</Provider>
)
}
现在你有一个 Provider
可以获取一些 data
并将其传递到 value
道具中。要从 functional component
中使用它,请像这样使用 useContext
import { context } from './Context'
const Component = () =>{
const data = useContext(context)
return <SomeJSX />
}
记住Component
必须在MyProvider
更新
- 什么是
{ children }
?
Component
声明中的所有内容都映射到 props.children
。
const App = () =>{
return(
<Button>
Title
</Button>
)
}
const Button = props =>{
const { children } = props
return(
<button className='fancy-button'>
{ children /* Title */}
</button>
)
}
像 ({ children })
一样声明它只是 const { children } = props
的快捷方式。我正在使用 children
这样你就可以像这样使用你的 Provider
<MyProvider>
<RestOfMyApp />
</MyProvider>
这里children
是RestOfMyApp
- 如何访问 Profile.js 中 Provider 的值?
使用createContext
。假设您的 Provider
的 value
属性 是 {foo: 'bar'}
const Component = () =>{
const content = useContext(context)
console.log(content) //{ foo : 'bar' }
}
- 如何像在 Provider 中那样双重声明常量?
打错了,我改成了MyProvider
从基于 class
的组件内部访问它
class Component extends React.Component{
render(){
const { Consumer } = context
return(
<Consumer>
{
context => console.log(contxt) // { foo: 'bar' }
}
</Consumer>
)
}
}