【问题标题】:React Context API: value is undefined in consumer componentReact Context API:消费者组件中未定义值
【发布时间】: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。

标签: reactjs react-router react-context react-state-management


【解决方案1】:
  1. 为了获得Consumer 的工作,您必须将它放在Provider 下。因为DashBoard不是Provider而是ComponentA,所以不能像DashBoard下面那样使用Consumer,也就是ComponentB
  2. 为了更好地组织组件,我推荐这种方法:

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

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

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

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

ComponentA -> DisplayTextData

ComponentB -> DisplayGraph

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

智能组件Dashboard

哑组件DisplayTextDataDisplayGraph

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    • 2019-06-03
    • 1970-01-01
    • 1970-01-01
    • 2019-08-11
    • 1970-01-01
    • 2019-07-16
    相关资源
    最近更新 更多