Reactjs React上下文API:消费者组件中未定义值
我一直试图使用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-->提供程序组件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
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;