我正在使用React(我的第一个React项目)建立一个电子商务网站,并且正在使用React Router管理我的页面。
我具有以下组件树结构:
<Router>
<BrowserRouter>
<Router>
<withRouter(Base)>
<Route>
<Base>
<BaseProvider>
<Context.Provider>
<Header>
<PageContent>
基本上是标准的React Router结构,有了Router,我得到了以下内容:
Base.js
import React, { Component } from 'react';
import { withRouter } from 'react-router';
import { Header } from './Header';
import { Footer } from './Footer';
import Provider from '../../BaseProvider';
class Base extends Component {
render() {
return (
<Provider>
<Header/>
<div className="container">{this.props.children}</div>
<Footer />
</Provider>
);
}
}
BaseProvider.js
import React, { Component, createContext } from 'react';
const Context = createContext();
const { Provider, Consumer } = Context;
class BaseProvider extends Component {
state = {
cart: [],
basketTotal: 0,
priceTotal: 0,
};
addProductToCart = product => {
const cart = { ...this.state.cart };
cart[product.id] = product;
this.setState({ cart, basketTotal: Object.keys(cart).length });
};
render() {
return (
<Provider
value={{ state: this.state, addProductToCart: this.addProductToCart }}
>
{this.props.children}
</Provider>
);
}
}
export { Consumer };
export default BaseProvider;
这从本质上给了我一个模板,因此我只是子页面,而不必每次都包含Header和Footer。
如果我想使用我的全局上下文,则每次都必须导入它,而且好像做错了什么,因为它已经在BaseProvider中导出,因此我肯定可以在任何页面上使用它吗? / p>
如果我要访问关于页面,我将获得相同的组件结构,但是如果不使用以下内容,则无法访问消费者:
import { Consumer } from '../../BaseProvider';
为什么即使每个文件都已导出并且位于BaseProvider的顶层,也必须对每个文件执行此操作?看来这是一个糟糕的模式,我不得不将其导入到大约20个文件中...
不导入它,我得到:
Line 67: 'Consumer' is not defined no-undef
我尝试仅将contextType添加到base,但是得到:警告:withRouter(Base):功能组件不支持contextType。
Base.contextType = Consumer;
我觉得我刚刚实施了这个错误,因为这种模式肯定可以更好地工作。
答案 0 :(得分:1)
我建议使用高阶组件-一种将其他组件包装成其他状态或功能的组件。
const CartConsumer = Component => {
return class extends React.Component {
render() {
return (
<MyContext.Consumer>
<Component />
</MyContext.Consumer>
)
}
}
}
然后在要使用它的任何组件中,只需将其包装在export语句中即可:
export default CartConsumer(ComponentWithContext)
这并不能避免完全导入,但比直接使用使用者要少得多。