用React / Redux Forms覆盖onChange行为

时间:2018-10-22 18:43:21

标签: reactjs redux redux-form

我正在React中构建一个复杂的表单,并试图将Redux Forms用作帮助工具。

该项目的要求是:

  1. 页面上的值会根据 输入字段(如Excel电子表格)

  2. 至少会有一个字段同时充当输入 字段和从属字段(可以更改,也可以更改 更改其他字段时)

  3. 我想控制状态何时改变。默认情况下,它将 输入更改时立即发生,但我宁愿延迟 像this example

第一个功能基本上遵循Redux Forms教程,我已经开始工作了。但是,其他两个需要修改在字段更新时会发生的情况,而我在弄清楚如何执行此操作时遇到了麻烦。我可以想象如何从头开始执行此操作,但想看看是否有一种使用此库的方法使事情更简单。

我的代码在GitHub上(旁边的问题,是否有人知道为什么我的GitHub pages site给出404?

1 个答案:

答案 0 :(得分:1)

您将必须创建一个自定义组件,以将其放置在redux-form的Field内部,并在其中保留内部状态,并在需要时与formReducer进行同步。

您可以通过以下几个步骤来实现:

  1. 创建一个自定义组件以在Field内部使用。此组件已注入with a meta and input prop

  2. 为您的React组件创建state,在其中您将跟踪最终将要发送到formReducer的数据。

  3. 在构造函数中,使用props.input.value设置初始状态。如果这样做,则可以为reduxForm使用'initialValues'对象。

  4. 使用connect中的react-redux,可以使用react-form的动作创建者。就您而言,您将使用change action creator

  5. 使用输入字段创建渲染函数,并触发change操作以修改此字段的formReducer值。

所以可以归结为这样的东西:

<Field
  name="daysPerWeek"
  component={MyCustomComponent} // 1
/>

...

class MyCustomComponent {
  constructor(props) {
    super(props);

    this.state = {
      value: props.input.value, // 2 and 3
    }
  }

  ....
}

4:

import { connect } from 'react-redux';
import { change } from 'react-form';

const mapDispatchToProps = (dispatch, ownProps) => ({
  ourCustomChange: (value) => dispatch(change(ownProps.meta.form, ownProps.input.name, value))
})

export default connect(undefined, mapDispatchToProps)(MyCustomComponent);

5:

....
 componentDidUpdate(prevProps, prevState) {
   if (prevState.value !== this.state.value) {
     this.debounceAndEmit();
   }
 }

 debounceAndEmit() {
   // Debounce for some time. Maybe use:
   // import { debounce } from 'throttle-debounce';
   // for that:
   debounce(2000, () => {
     this.props.ourCustomChange(this.state.value)
   })
 }

 handleChange(event) {
   // Do things here like trimming the string, regex, whatever.
   this.setState({ value: event.target.value })
 }

  render() {
    return (
      <input
        {...this.props.input} // Includes standard redux-form bindings for input fields. 
        value={this.state.value}
        onChange={this.handleChange.bind(this)}
      />
    )
  }
....

在某些情况下,您可能也必须使用blur action creator。例如,当您在输入字段之外单击时正在做事时。

如果您希望表单字段根据其他字段进行更改,则应使用selectors将其值注入到自定义组件中以对此进行响应。

这能回答您的问题吗?