使用功能组件中的 REST Api 调用更新 React Context

Oct*_*ian 11 reactjs react-context

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

我已经尝试过这篇博客文章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
Run Code Online (Sandbox Code Playgroud)

这是我尝试从上下文访问数据的功能组件

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)
    }
  }));
Run Code Online (Sandbox Code Playgroud)

我可以看到获取请求在浏览器控制台的网络部分获取数据,但上下文没有更新。

我试过在 textContext.js 中这样做。

export async function callTextApi () {
  await fetch(process.env.REACT_APP_TEXT_API)
    .then(res => res.json())
    .then(json => {
      return json;
    })
}


Run Code Online (Sandbox Code Playgroud)

我试图使用 useEffect 函数获取 Profile.js 中的数据

 const [text, setText] = useState(null);
  useEffect(()=> {
    setText (callTextApi())
  },[])
Run Code Online (Sandbox Code Playgroud)

这是我第一次使用 React.context 并且非常混乱。我做错了什么或错过了什么?

Dup*_*cas 17

你在这里有很多问题。fetching并且应该Provider通过修改value属性在内部进行更改。useContext接收整个Context对象,而不仅仅是Provider. 检查以下内容

//Context.js
export const context = React.createContext()
Run Code Online (Sandbox Code Playgroud)

现在在你的 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>
   )
}
Run Code Online (Sandbox Code Playgroud)

现在你有一个Provider可以获取一些data并将其传递到valueprop 中的对象。为了从内部消耗它functional component使用useContext这样的

import { context } from './Context'

const Component = () =>{
    const data = useContext(context)

    return <SomeJSX />
}
Run Code Online (Sandbox Code Playgroud)

请记住,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>
    )
}
Run Code Online (Sandbox Code Playgroud)

声明它就像({ children })它只是const { children } = props. 我正在使用,children以便您可以Provider像这样使用

<MyProvider>
    <RestOfMyApp />
</MyProvider>
Run Code Online (Sandbox Code Playgroud)

childrenRestOfMyApp

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

使用createContext. 让我们假设value你的财产Provider{foo: 'bar'}

const Component = () =>{
    const content = useContext(context)

    console.log(content) //{ foo : 'bar' }
}
Run Code Online (Sandbox Code Playgroud)
  • 您如何像在 Provider 中所做的那样双重声明一个常量?

打错了,我改成 MyProvider

class基于组件的内部访问它

class Component extends React.Component{
    render(){
        const { Consumer } = context
        return(
             <Consumer>
                 {
                     context => console.log(contxt) // { foo: 'bar' }
                 }
             </Consumer>
        )
    }
}
Run Code Online (Sandbox Code Playgroud)