React Context API:消费者组件中未定义值

Posted

技术标签:

【中文标题】React Context API:消费者组件中未定义值【英文标题】:React Context API: value is undefined in consumer component 【发布时间】:2020-07-17 14:43:34 【问题描述】:

我一直在尝试使用 React ContextAPI 向我的反应应用程序添加状态管理,但我遇到了一个问题。我正在使用类组件,这里的想法是使用Axios从组件中获取数据并将数据传递到仪表板以汇总数据。

组件 A --> 提供者组件

组件 B --> 消费者组件

Component C --> Dashboard --> 使用ComponentB

当我浏览仪表板时,状态值总是未定义。 关于如何解决这个问题的任何建议?感谢您的帮助。

package.json “反应”:“^16.12.0”, “反应域”:“^16.12.0”, "react-router-dom": "^5.1.2", “反应脚本”:“3.3.0”,

App.js

import React,  Component  from "react";
import "./App.css";
import  Route, Switch  from "react-router-dom";
import Dashboard from "./components/dashboard";
import ComponentA from "./components/a"
import "rsuite/dist/styles/rsuite-default.min.css";
import SomeContext from "./context/context.js";

class App extends Component 
state = ;
render() 
 return (
   <React.Fragment>
     <Sidebar />
       <Switch>
         <Route path="/dashboard" component=Dashboard />
         <Route path="/a" component=ComponentA />
       </Switch>
   </React.Fragment>
 );



export default App;

SomeContext.js


    import React from "react";

    const SomeContext = React.createContext();
    SomeContext.displayName = "SomeContext";


    export default SomeContext;

组件 A --> 提供者组件

import React,  Component  from "react";
import axios from "axios";
import  Card, CardHeader, Table, Container, Row  from "reactstrap";
import SomeContext from "./context/context.js";
class ComponentA extends Component 
  state = 
    posts: [],
  ;
  async componentDidMount() 
    const  data: posts  = await axios.get("http://localhost:5000/api");
    this.setState( posts );
    console.log(posts);
  

  render() 
    return (
      <div className="main-content" ref="main-content">

        <Container fluid>
          <SomeContext.Provider value= state:this.state >
            <ComponentB/>   
            **.....Some component code **

            </SomeContext.Provider>
        </Container>
      </div>
    );
  


export default ComponentA;

组件 B -- 使用组件 A 的数据

import React,  Component  from "react";
import SomeContext from "./context/context.js";

class ComponentB extends Component 
static contextType = SomeContext;

  render() 
    return (
      <SomeContext.Consumer>
        (dashboard) => (
          <div>Data: dashboard console.log(dashboard) </div>

        )
    </SomeContext.Consumer>
        );
      
    

export default ComponentB;

仪表板

import React,  Component  from "react";
import ComponentB from "./components/b";

class Dashboard extends Component 
  render() 
    return (
      <div className="main-content">
        <ComponentB />
      </div>
    );
  


export default Dashboard;

【问题讨论】:

您的仪表板组件看起来不像您的 Provider 的子组件 您必须将您的Consumer 放在您的Provider 下方(内部)才能使其正常工作。 ComponentB,即Consumer,不在Provider下,即ComponentA @CamSong 感谢您的回复,我在提供程序 ComponentA 中添加了 ComponentB。但我仍然不确定 DashBoard 下的ComponentB 是没有意义的,不是吗?你还有什么未定义的? 好的,让我试一试,想以正确的方式设置应用程序,以便将来可以增长。再次感谢@CamSong。 【参考方案1】:
    为了获得Consumer 的工作,您必须将它放在Provider 下。因为DashBoard不是Provider而是ComponentA,所以不能像DashBoard下面那样使用Consumer,也就是ComponentB。 为了更好地组织组件,我推荐这种方法:

DashBoard 将是父层(容器),它负责两件事:数据获取和上下文提供者。

ComponentA 现在位于DashBoard 之下,其作用仍然相同:显示文本数据。另外,从Provider中检索数据也变成了Consumer,现在是DashBoard

最后,ComponentB 嵌套在 DashBoard 和负责显示图表的 ComponentA 下。

还请考虑使用有意义的名称来命名您的组件。例如:

ComponentA -> DisplayTextData

ComponentB -> DisplayGraph

所以最后你会得到这样的东西:

智能组件Dashboard

哑组件DisplayTextDataDisplayGraph

如果您不知道 smart/dumb 组件是什么意思,请参阅 Dan Abramov 撰写的这篇文章:here。请记住,最好减少智能组件的数量,增加哑组件的数量。

    为了让您的组件保持清洁,请考虑切换到 Redux。使用 Redux 进行状态管理的众多优势之一是,它允许您避免调用异步操作,也就是在组件内部获取数据等副作用。

【讨论】:

以上是关于React Context API:消费者组件中未定义值的主要内容,如果未能解决你的问题,请参考以下文章

React context API-我如何从 useEffect 钩子中分派一个动作?

react--context,高阶组件,hook

React中不常用的功能——Context

React Context API - 孩子/消费者可以请求提供者更改值吗?

包含 Context.Provider 和 Context.Consumer 的 React Context 测试组件

如何通过 React Context 传递多个参数(从消费者到提供者)?