如何在 redux-form 的 <Field> 中有条件地渲染组件

How to conditionally render component in <Field> of redux-form

在我的代码中,试图通过一个名为 renderDatePicker() 的函数在 Redux Form 的 <Field> 组件中呈现 <DatePicker>。此函数链接到 handleClick() 函数,其中状态变量 isOpen 设置为 true

所以理想情况下,onClick 应该呈现 <DatePicker>,因为它设置为可见。但是代码不会更新任何东西。我哪里做错了?

注意:在没有 <Field component=...> 的帮助下直接单独渲染 <DatePicker>,效果很好。

用于调试,完整代码在CodeSandbox中,

SimpleForm.js

import React from "react";
import { reduxForm } from "redux-form";
import { Field } from "redux-form";
import DatePicker from "react-mobile-datepicker";

class SimpleForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      time: new Date(),
      isOpen: false
    };
    this.handleClick = this.handleClick.bind(this);
  }

  renderDatePicker = () => (
    <DatePicker
      value={this.state.time}
      isOpen={this.state.isOpen}
      onSelect={this.handleSelect}
      onCancel={this.handleCancel}
    />
  );

  handleClick() {
    this.setState({ isOpen: true }, function() {
      console.log(this.state.isOpen);
    });
  }

  handleCancel = () => {
    this.setState({ isOpen: false });
  };

  handleSelect = time => {
    this.setState({ time, isOpen: false });
  };

  render() {
    return (
      <div>
        <button className="select-btn" onClick={this.handleClick}>
          select time
        </button>
        <Field
          name="date"
          type="date"
          component={this.renderDatePicker}
          label={"date"}
        />
      </div>
    );
  }
}

export default reduxForm({
  form: "simple" // a unique identifier for this form
})(SimpleForm);

这种行为的原因在于 react-form 的 Field 组件的实现。它对其所有属性进行浅层比较,以决定是否应该重新渲染。您可以随意更改组件的 state,对 this.renderDatePicker 的引用不会更改。

Field 将包括 onChange 处理程序和当前 value 的属性传递到字段的 component 无状态函数调用中以通知更改,但这实际上并不是在此处申请,因为您的切换按钮在该字段之外。

所以我想到的一个选择是将您的按钮移动到呈现的字段中,然后调用 onChange(!value)

更简单但更肮脏的选择是在你的 component 属性 中使用箭头函数:component={() => this.renderDatePicker()} - 这个实例随着你的 [=20= 的每次重新渲染而改变](即如果 state 发生变化),因此它会带来成本,但根据您应用程序的复杂性,成本可以忽略不计。为了减轻影响,您可以实现 shouldComponentUpdate(就像 redux-form 的 Field 所做的那样)来根据当前和下一个 isOpen 状态决定是否应该重新渲染。

在 redux-form 中查看此位以获取更多详细信息:https://github.com/erikras/redux-form/blob/master/src/createField.js#L44