【问题标题】:Redux-Form Field won't update with value of <input> inside itRedux-Form 字段不会用其中的 <input> 值更新
【发布时间】:2023-03-09 17:07:01
【问题描述】:

我正在尝试在 React 中设计一个可键入的输入组件,它被包装在 Redux-Form Field 中。但是当 HTML 的 &lt;input&gt; 标记的值发生变化时,Field 的值不会更新。

Field 定义为:

<Field
    name="inputTextBox"
    type="text"
    component={CustomInputComponent}
</Field>

CustomInputComponent定义为:

    class CustomInputComponent extends Component {

        constructor() {
            super();
            this.state= {
                value: undefined
            };

        /* updates the state of CustomInputComponent with the current value typed inside <input> */
        setInputValueText = (value) => {
            this.setState({
                ...this.state,
                value
            })
        };

        render() {
            return (
                <input type="text" value={this.state.value} onInput={event => this.setInputValueText(event.target.value)} />
            )

    }

每当输入&lt;input&gt; 标签时,CustomInputComponent 的状态会成功更改,但上面包含CustomInputComponentField 的值不会更改。我正在尝试通过以下方式访问Field 的值:

const selector = formValueSelector('myForm')
let currentInput = selector(state, 'inputTextBox')

我希望currentInput 包含在input 中键入的当前值。我可能会错过什么?

【问题讨论】:

    标签: reactjs redux react-redux redux-form


    【解决方案1】:

    几种方法:

    • 将 Redux 表单 字段的数据/方法 传递给 child(推荐 - 请参阅下文了解最低要求)。
    • 利用 React 状态,将其设置为 Redux 字段,然后将其从 父母孩子

    https://codesandbox.io/s/z3xnjv4w7m(将 Redux 字段数据/方法传递给子级) https://codesandbox.io/s/m4x7z7o429(通过 React 状态控制 Redux Fields)


    将 Redux 字段的数据/方法传递给子示例

    InputForm.js

    import React, { Component } from "react";
    import { Form, Field, reduxForm } from "redux-form";
    import CustomInputComponent from "./customInputComponent";
    
    const isRequired = value => (!value ? "Required" : undefined);
    
    class InputForm extends Component {
      handleFormSubmit = ({ inputTextBox }) =>
        alert(`Value of custom input: ${inputTextBox}`);
    
      render = () => (
        <div style={{ height: 300, width: 500 }}>
          <h1 style={{ textAlign: "center" }}>Input Form</h1>
          <hr />
          <Form onSubmit={this.props.handleSubmit(this.handleFormSubmit)}>
            <div style={{ height: 70 }}>
              <Field
                className="uk-input"
                component={CustomInputComponent}
                name="inputTextBox"
                type="text"
                placeholder="Write something..."
                validate={[isRequired]}
              />
            </div>
            <button
              type="submit"
              className="uk-button uk-button-primary uk-button-large"
              disabled={this.props.submitting}
            >
              Submit
            </button>
            <button
              type="button"
              className="uk-button uk-button-default uk-button-large"
              disabled={this.props.pristine || this.props.submitting}
              onClick={this.props.reset}
              style={{ float: "right" }}
            >
              Clear
            </button>
          </Form>
        </div>
      );
    }
    
    export default reduxForm({ form: "InputForm" })(InputForm);
    

    customInputField.js

    import React, { Fragment } from "react";
    
    export default ({
      children,
      input,
      meta: { invalid, touched, error },
      ...props
    }) => (
      <Fragment>
        <input {...input} {...props} />
        {touched && error && <div style={{ color: "red" }}>{error}</div>}
      </Fragment>
    

    最低要求

    至少,Redux Field 的 input.onChange 方法和 input.value 需要从父级传递给子级。

    家长

    <Field
       component={CustomInputComponent}
       name="inputTextBox"
    />  
    

    儿童

    export default ({ input: { onChange, value }}) => (
      <input
        type="text"
        placeholder="Write something..."
        className="uk-input"
        onChange={onChange}
        value={value}
      />
    );
    

    通过反应状态控制字段

    ControlledInputForm.js

    import React, { Component } from "react";
    import { Form, Field, reduxForm, change } from "redux-form";
    import CustomInputComponent from "./customInputComponent";
    
    const isRequired = value => (!value ? "Required" : undefined);
    
    class ControlledInputForm extends Component {
      state = { value: "" };
    
      handleFormSubmit = ({ inputTextBox }) =>
        alert(`Value of custom input: ${inputTextBox}`);
    
      handleChange = e => {
        this.setState({ value: e.target.value }, () => {
          this.props.change("inputTextBox", this.state.value);
        });
      };
    
      resetForm = () => this.setState({ value: "" }, () => this.props.reset());
    
      render = () => (
        <div style={{ height: 300, width: 500 }}>
          <h1 style={{ textAlign: "center" }}>Controlled Input Form</h1>
          <hr />
          <Form onSubmit={this.props.handleSubmit(this.handleFormSubmit)}>
            <div style={{ height: 70 }}>
              <Field
                className="uk-input"
                component={CustomInputComponent}
                name="inputTextBox"
                placeholder="Write something..."
                type="text"
                handleChange={this.handleChange}
                controlledValue={this.state.value}
                validate={[isRequired]}
              />
            </div>
            <button
              type="submit"
              className="uk-button uk-button-primary uk-button-large"
              disabled={this.props.submitting}
            >
              Submit
            </button>
            <button
              type="button"
              className="uk-button uk-button-default uk-button-large"
              disabled={this.props.pristine || this.props.submitting}
              onClick={this.resetForm}
              style={{ float: "right" }}
            >
              Clear
            </button>
          </Form>
        </div>
      );
    }
    
    export default reduxForm({
      form: "ControlledInputForm",
      fields: ["inputTextBox"]
    })(ControlledInputForm);
    

    customInputComponent.js

    import React, { Fragment } from "react";
    
    export default ({
      meta: { invalid, touched, error },
      handleChange,
      controlledValue,
      ...props
    }) => (
      <Fragment>
        <input {...props} value={controlledValue} onChange={handleChange} />
        {touched && error && <div style={{ color: "red" }}>{error}</div>}
      </Fragment>
    );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-03
      • 2018-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-13
      相关资源
      最近更新 更多