【问题标题】:How to conditionally render component in <Field> of redux-form如何有条件地在 redux-form 的 <Field> 中渲染组件
【发布时间】:2019-08-07 14:53:11
【问题描述】:

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

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

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

为了调试,完整的代码在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);

【问题讨论】:

    标签: reactjs datepicker field redux-form


    【解决方案1】:

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

    Field 将包括onChange 处理程序和当前value 在内的属性传递到字段的component 无状态函数调用以通知更改,但这并不真正适用于此处,因为您的切换按钮不在字段。

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

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

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

    【讨论】:

    • 有帮助!我也在setState > handleClick() 的回调中尝试了this.forceupdate()。但这没有任何效果。
    猜你喜欢
    • 2020-11-17
    • 1970-01-01
    • 1970-01-01
    • 2022-07-23
    • 2018-09-13
    • 2019-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多