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
哑组件:DisplayTextData
、DisplayGraph
如果您不知道 smart/dumb 组件是什么意思,请参阅 Dan Abramov 撰写的这篇文章:here。请记住,最好减少智能组件的数量,增加哑组件的数量。
-
为了让您的组件保持清洁,请考虑切换到 Redux。使用 Redux 进行状态管理的众多优势之一是,它允许您避免调用异步操作,也就是在组件内部获取数据等副作用。
【讨论】:
以上是关于React Context API:消费者组件中未定义值的主要内容,如果未能解决你的问题,请参考以下文章
React context API-我如何从 useEffect 钩子中分派一个动作?
React Context API - 孩子/消费者可以请求提供者更改值吗?