我完全迷失在react-redux容器(即连接器)概念上,因为它没有按照我的预期行事。我的问题是直截了当的,对我来说是合理的,但我找不到一个如何实现它的写得很好的例子。
我们假设有一个react组件连接到具有产品上下文的商店,我们将调用此组件ProductContext
。
此外,我们想要在整个应用程序中自由地重用ProductContext
,以避免在可能需要产品的每个其他组件上调度操作的样板代码。
说明这就是我的意思:
来自DiscountuedProducts的:
<ProductContext >
// do something with props from container
</ProductContext >
来自SeasonalProducts的:
<ProductContext >
// do something with props from container
</ProductContext >
从我在react-redux看到的例子来看,在我看来,他们的容器将容器本身的季节性和停产产品混为一谈。那怎么可重复使用?
来自ProductContextComponent的:
<section >
<DiscontinuedProducts />
<SeasonalProducts />
</section >
使事情变得复杂,同时试图对这个最令人沮丧的问题保持冷静,并且#34;模糊不清的&#34;似乎是我收到的唯一回复。
所以这是我的ProductContext
:
@connect(state => ({
products: state.productsReducer.products
}))
export default class ProductContext extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
const { dispatch } = this.props;
const clientId = this.context.clientInfo._id;
dispatch(fetchProductsIfNeeded(clientId));
}
// get from parent
static contextTypes = {
clientInfo: PropTypes.object.isRequired
};
static propTypes = {
children: PropTypes.node.isRequired,
dispatch: PropTypes.func.isRequired,
products: PropTypes.array
};
render() {
if (!this.props.products) return <Plugins.Loading />;
.....
return (
// I want to put the products array here
);
}
};
然后我的想法是,如果我这样做:
来自DiscountuedProducts的:
<ProductContext >
// do something with props from container
</ProductContext >
DiscontinuedProducts
应该了解这些产品,并且可以简单地过滤已停产的产品。
我对此完全错了吗?欲望这是不合理的吗?
如果有人知道网上有一个详尽的示例,说明如何实现这一目标,我将非常感谢它向我指出。我已经花了一个多星期来解决这个问题,并准备放弃react-redux。
更新:以下使用HOC的解决方案。
答案 0 :(得分:1)
如果有人知道网上有一个详尽的例子,说明如何实现这一点,我将非常感谢它被指出给我。
示例代码来自:shopping-cart/containers/CartContainer.js
让我们说我们有一个反应组件连接到具有产品上下文的商店
产品 商店,用户等商店等。所有商品都有一商店。您应该使用reducer来获取完整存储并减少组件所需的内容。
来自示例:
import { getTotal, getCartProducts } from '../reducers'
const mapStateToProps = (state) => {
return {
products: getCartProducts(state),
total: getTotal(state)
}
}
这里是整个商店。
让我们说我们希望在整个应用程序中大量重用ProductContext,以避免调度操作的样板代码
组件不会调度操作,它们会调用传递给它们的函数。这些函数位于一个动作模块中,您可以将其导入并作为道具传递给容器。反过来,容器将这些函数传递给组件道具。
来自示例:
import { checkout } from '../actions'
CartContainer.propTypes = {
checkout: PropTypes.func.isRequired
}
connect(mapStateToProps,
{ checkout }
)(CartContainer)
连接做什么,它订阅商店更改,调用地图功能,与常量道具合并(这里是动作功能),并为容器分配新道具。
DiscontinuedProducts应该了解这些产品,并且可以简单地过滤已停产的产品
这实际上就是现货。你提到的知识是一个商店,它绝对应该在reducer中过滤。
希望这可以解决问题。
答案 1 :(得分:0)
我找到了一种更实用的方法来利用来自redux的重复数据而不是文档。如果我已经在更高级别完成了一次,那么重复mapToProps并在每个有福的组件上调度实例化是没有意义的,并且存在解决方案。确保您的应用符合Babel 6标准,因为我使用了装饰器。
<强> 1。我为上下文创建了一个更高阶的组件....
<强>产品context.js 强>:
import React, { Component, PropTypes } from 'react';
// redux
import { connect } from 'react-redux';
import { fetchProductsIfNeeded } from '../../redux/actions/products-actions';
// productsReducer is already in state from index.js w/configureStore
@connect(state => ({
products: state.productsReducer.products
}))
export default function ProductContext(Comp) {
return (
class extends Component {
static propTypes = {
children: PropTypes.node,
dispatch: PropTypes.func.isRequired,
products: PropTypes.array
};
static contextTypes = {
clientInfo: PropTypes.object.isRequired;
};
componentDidMount() {
const { dispatch } = this.props;
const clientId = this.context.clientInfo._id;
dispatch(fetchProductsIfNeeded(clientId));
}
render() {
if (!this.props.products) return (<div>Loading products ..</div>);
return (
<Comp products={ this.props.products }>
{ this.props.children }
</Comp>
)
}
}
)
}
<强> 2。组件利用product-context.js
<强>转盘-slider.js:强>
import React, { Component, PropTypes } from 'react';
......
import ProductContext from '../../../context/product-context';
@Radium
@ProductContext
export default class CarouselSlider extends Component {
constructor(props) {
super(props); }
......
static showSlideShow(carouselSlides) {
carouselSlides.map((slide, index) => {
......
results.push (
......
)
});
return results;
}
render() {
const carouselSlides = this.props.products;
const results = CarouselSlider.showSlideShow(carouselSlides);
return (
<div id="Carousel" className="animation" ref="Carousel">
{ results }
</div>
);
}
}
所以你去吧。我需要的只是装饰器对产品上下文的引用,作为HOC,它返回带有产品prop的carousel组件。
我为自己保存了至少10行重复代码,并从较低的组件中删除了所有相关的contextType,因为使用装饰器不再需要它。
希望这个真实世界的例子有所帮助,因为我讨厌这些例子。