首页 > 解决方案 > 在功能组件中使用 REST Api 调用更新 React Context

问题描述

我正在尝试使用 API 调用后端 REST API 产生的数据来更新 React App 的上下文。问题是我无法同步该功能。

我已经尝试过这篇博文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 并且很混乱。我做错了什么或错过了什么?

标签: reactjsreact-context

解决方案


你这里有很多问题。fetching并且应该Provider通过修改value属性在内部进行更改。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并将其传递到valueprop 中的方法。从这样的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>

这里childrenRestOfMyApp

  • 如何访问 Profile.js 中 Provider 的值?

使用createContext. 假设value您的财产Provider{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>
        )
    }
}

推荐阅读