Reactjs React上下文API:消费者组件中未定义值

Reactjs React上下文API:消费者组件中未定义值,reactjs,react-router,react-context,react-state-management,Reactjs,React Router,React Context,React State Management,我一直试图使用react-ContextAPI将状态管理添加到我的react应用程序中,但遇到了一个问题。我使用类组件,其思想是使用Axios从组件获取数据,并将数据传递到仪表板以汇总数据 组件-->提供程序组件 组件B-->用户组件 组件C-->仪表板-->使用组件B 当我浏览仪表板时,状态值总是未定义。 关于如何解决这个问题,有什么建议吗?谢谢你的帮助 package.json “反应”:“^16.12.0”, “react dom”:“^16.12.0”, “反应路由器dom”:“^5.1

我一直试图使用react-ContextAPI将状态管理添加到我的react应用程序中,但遇到了一个问题。我使用类组件,其思想是使用Axios从组件获取数据,并将数据传递到仪表板以汇总数据

组件-->提供程序组件

组件B-->用户组件

组件C-->仪表板-->使用组件B

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

package.json “反应”:“^16.12.0”, “react dom”:“^16.12.0”, “反应路由器dom”:“^5.1.2”, “反应脚本”:“3.3.0”

App.js

组件A-->提供程序组件

import React,{Component}来自“React”;
从“axios”导入axios;
从“reactstrap”导入{Card,CardHeader,Table,Container,Row};
从“/context/context.js”导入SomeContext;
类ComponentA扩展了组件{
状态={
员额:[],
};
异步组件didmount(){
const{data:posts}=wait axios.get(“http://localhost:5000/api");
this.setState({posts});
控制台日志(posts);
}
render(){
返回(
**…一些组件代码**
);
}
}
导出默认组件a;
组件B——使用组件A中的数据

import React,{Component}来自“React”;
从“/context/context.js”导入SomeContext;
类ComponentB扩展了组件{
静态contextType=SomeContext;
render(){
返回(
{(仪表板)=>(
数据:{dashboard}{console.log(dashboard)}
)}
);
}
}
导出默认组件B;
仪表板

import React,{Component}来自“React”;
从“/components/b”导入组件b;
类仪表板扩展组件{
render(){
返回(
);
}
}
导出默认仪表板;
  • 要使
    消费者
    工作,必须将其置于
    提供者
    下。由于
    仪表板
    不是
    提供者
    而是
    组件a
    ,因此您不能使用
    仪表板
    下的
    消费者
    ,即
    组件b
  • 为了更好地组织组件,我建议采用以下方法:
  • DashBoard
    将是父层(容器),负责两件事:数据获取和上下文提供程序

    ComponentA
    现在位于
    DashBoard
    下,其角色仍然相同:显示文本数据。此外,它还成为一个
    消费者
    ,从
    提供者
    检索数据,现在是
    仪表板

    最后,
    ComponentB
    嵌套在
    DashBoard
    ComponentA
    下,后者负责显示图形

    也请考虑使用一个有意义的名称来命名组件。例如:

    ComponentA
    ->
    DisplayTextData

    ComponentB
    ->
    DisplayGraph

    最后,你会有这样的结果:

    智能组件
    仪表板

    哑组件
    显示文本数据
    显示图形

    如果您不知道smart/dumb组件的含义,请参阅Dan Abramov撰写的这篇文章:。请记住,减少智能组件的数量,增加哑组件的数量始终是一个好的做法。

    为了保持您的组件保持清洁,请考虑切换到ReDux。使用Redux进行状态管理的许多优点之一是,它允许您避免调用异步操作,也就是避免组件内部的数据获取等副作用
    您的仪表板组件看起来不像是提供商的子组件您必须将
    消费者
    放在
    提供商
    的下方(内部)才能正常工作
    ComponentB
    ,它是
    消费者
    ,不在
    提供商
    ,它是
    ComponentA
    @CamSong感谢您的回复,我在提供商组件A中添加了ComponentB。但是我仍然没有定义
    仪表板下的
    组件b
    没有意义,不是吗?你仍然得到什么未定义的?好吧,让我试试,想把应用程序设置成正确的方式,这样它就可以在未来发展。再次感谢@CamSong。
    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;
    
    
    
        import React from "react";
    
        const SomeContext = React.createContext();
        SomeContext.displayName = "SomeContext";
    
    
        export default SomeContext;
    
    
    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;
    
    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;