Redux 表单,有没有一种很好的方法来制作一个可以切换所有功能的复选框列表?

Redux forms, is there a good way to make a checkbox list with toggle all functionality?

我使用的是最新的 redux-form v6.5.0。 我想知道使用库中的内容切换所有组件的最佳解决方案是什么。

我最终在我的表单中添加了不同的字段并播放了 redux 表单动作创建器和反应生命周期,但我不确定这是否是最佳解决方案。

有没有例子?

到目前为止我所做的是在渲染中使用这样的结构:

...

<Field
    name='toggleAll'
    component={Ckbox}
    onChange={this.toggleAllProfile} />
<div>
{
    SUB_FIELDS.map((field, i) => (
        <Field key={i} name={field} component={Ckbox} />
    ))
}
</div>

子字段是一组名称,如下所示:

const SUB_FIELDS = ['field1', field2, field3, ...];

然后我有一个 componentWillReceiveProps,我在其中检查子字段是否已选中或未相应地切换 toggleAll 复选框。

componentWillReceiveProps(nextProps) {
  const {
    profiles,
  } = nextProps;
  const allFieldsChecked = SUB_FIELDS.filter(
    el => nextProps[el]
  ).length === SUB_FIELDS.length;

  if (
    allFieldsChecked &&
    toggleAll
  ) {
    return;
  } else if (
    allFieldsChecked &&
    !toggleAll
  ) {
    this.props.change('toggleAll', true);
  } else if (
    !allFieldsChecked &&
    profiles
  ) {
    this.props.change('toggleAll', false);
  }
}

以及一种在 toggleAll onChange 上切换它们的方法

toggleAllProfile = (e) => {
  SUB_FIELDS.forEach(field => {
    this.props.change(field, e.target.checked);
  });
};

这工作正常,但这些字段并不是我的表单组件中的唯一字段,添加更多具有不同需求的字段会变得非常混乱。

我试过使用 Fields 组件,但看起来渲染太多了。

我想把它们放在一个单独的组件中,但我需要用另一种形式包装这个组件,所以我最终会有 2 个 redux-form,我错了吗?

I thought to make them in a separate component but then I will need to wrap this component in another form, so I'll end up having 2 redux-forms am I wrong?

幸运的是,是的,你错了!你只需要用 reduxForm() 装饰一个顶级组件。该组件可以渲染也可以使用 <Field /> 或其他 redux-form 组件的子组件。您 可能 想要使用来自 redux-form 的其他选择器来装饰这些子组件以注入相关的表单状态,但您不必使用 reduxForm().[= 来装饰它18=]

I've tried using the Fields component but then it looked like too many renders.

当它是 checked/unchecked 或您的子字段之一是 checked/unchecked 时,它应该只 re-render。如果它在一个单独的组件中,只呈现一个复选框,那应该不是一个巨大的性能问题。如果您看到的 re-render 多于此,则值得研究原因。找到原因可以让您学到重要的经验教训,了解如何在未来防止性能问题。

你现在的东西工作正常,看起来也不错。使用 <Fields /> 可能是推荐的方式。

编辑

澄清一下,如果您制作一个单独的组件,它应该 只渲染您的toggle-all 复选框;您应该与此分开呈现您的子字段。当您只检查了子字段 0 时,这将防止子字段 1-n re-rendering。