Say I have a functional React presentation component, like so:
const Functional = (props) => {
// do some stuff
return (
<div>
// more HTML based on the props
</div>
);
}
Functional.propTypes = {
prop1: React.PropTypes.string.isRequired,
prop2: React.PropTypes.string.isRequired,
// ...
};
If I'm using Redux and following the container component pattern, what would be the best way to render a dynamic number of these <Functional/>
components inside a wrapper component, based on elements inside a array (which is inside my Redux state)?
Eg My Redux state might look like this:
{
functionalItems: [
{
prop1: 'x1',
prop2: 'y1',
// ...
},
{
prop1: 'x2',
prop2: 'y2'
},
// ... more items
],
// ...
}
So each item in the functionalItems
array should correspond to a <Functional/>
component, which all get rendered adjacent to each other.
This is the second time I have come across this problem, so I'm hoping that it's common enough that there is good solution out there.
I'll post the solutions I can come up with (but which have undesirable traits), as answers to this question.
I'd like to suggest that you pass the entire array to the wrapper component like this:
const mapStateToProps = (state) => ({
items: getFunctionalItems(state),
// ...
});
and then in your Wrapper.jsx
, do it like this:
const Wrapper = (props) => {
const elements = props.items.map((item, index) => {
<Functional prop1={ item.prop1 } prop2={ item.prop2 } ...
key={ ... /* you can use index here */ }/>
});
return (
<div>
{ elements }
</div>
);
};
...where getFunctionalItems()
is an accessor function that is the canonical means of accessing the functional items from the state.
This way, you can handle changes in state structure, or a different rendering layout. (ergo more robust (I think)). And it looks more like following the Single Responsibility Principle.
<Functional/>
prop values. <Functional/>
prop values. Wrapper.jsx:
const Wrapper = (props) => {
const elements = [];
for (let i = 0; i < props.quantity; i++) {
elements.push(
<Functional prop1={ getPropValue1(i) } prop2={ getPropValue2(i) } ...
key={ ... }/>
);
}
return (
<div>
{ elements }
</div>
);
};
Wrapper.propTypes = {
quantity: React.PropTypes.number.isRequired,
getPropValue1: React.PropTypes.func.isRequired,
getPropValue2: React.PropTypes.func.isRequired,
// ...
};
ContainerComponent.js:
const mapStateToProps = (state) => ({
quantity: state.functionalItems.length,
getPropValue1: (index) => state.functionalItems[index].prop1,
getPropValue2: (index) => state.functionalItems[index].prop2,
// ...
});
const ContainerComponent = connect(mapStateToProps)(Wrapper);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.