简体   繁体   English

使用Redux容器组件模式呈现动态数量的React子组件的可靠方法是什么?

[英]What is a robust way of rendering a dynamic quantity of React child components, using the Redux container component pattern?

Say I have a functional React presentation component, like so: 说我有一个功能性的React演示组件,像这样:

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)? 如果我使用Redux并遵循容器组件模式,那么基于数组中的元素(在我的Redux状态内),在包装器组件内呈现这些<Functional/>组件的动态数量的最佳方法是什么? ?

Eg My Redux state might look like this: 例如,我的Redux状态可能如下所示:

{
  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. 因此, functionalItems数组中的每个项目都应对应一个<Functional/>组件,所有组件都将呈现为彼此相邻。

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: 然后在您的Wrapper.jsx ,如下所示:

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. ...其中getFunctionalItems()是访问器函数,是从状态访问功能项的规范方法。

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. 它看起来更像遵循单一责任原则。

Solution Description 解决方案说明

  • Create a wrapper functional presentation component that takes in a quantity and functions to fetch the <Functional/> prop values. 创建一个包装函数表示组件,该组件使用一定数量和功能来获取<Functional/>道具值。
  • Create a container component that connects to this new wrapper component and passes in the quantity (based on the Redux state) and accessor functions to fetch the <Functional/> prop values. 创建一个容器组件,该容器组件连接到此新包装器组件,并传入数量(基于Redux状态)和访问器函数以获取<Functional/>道具值。

Example Code 范例程式码

Wrapper.jsx: 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: 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM