Redux-Form Field 不会更新其中的 <input> 值
Redux-Form Field won't update with value of <input> inside it
我正在尝试在 React 中设计一个可输入的输入组件,它被包装在一个 Redux-Form Field
中。但是当 HTML <input>
标签的值改变时 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)} />
)
}
每当输入 <input>
标签时,CustomInputComponent
的状态会成功更改,但上面包含 CustomInputComponent
的 Field
的值不会改变。我正在尝试通过以下方式访问 Field
的值:
const selector = formValueSelector('myForm')
let currentInput = selector(state, 'inputTextBox')
我希望 currentInput
包含在 input
中键入的当前值。我可能缺少什么?
几种方法:
- 将 Redux 表单 Field 的 data/methods 传递给 child(推荐——最低要求见下文) .
- 利用 React 状态,将其设置为 Redux 字段,然后从
parent 到 child.
https://codesandbox.io/s/z3xnjv4w7m(将 Redux 字段 data/methods 传递给 child)
https://codesandbox.io/s/m4x7z7o429(通过 React state 控制 Redux Fields)
将 Redux 字段的 Data/Methods 传递给 Child 示例
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
需要从 parent 传递到 child。
Parent
<Field
component={CustomInputComponent}
name="inputTextBox"
/>
Child
export default ({ input: { onChange, value }}) => (
<input
type="text"
placeholder="Write something..."
className="uk-input"
onChange={onChange}
value={value}
/>
);
通过 React 状态控制字段
控制InputForm.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>
);
我正在尝试在 React 中设计一个可输入的输入组件,它被包装在一个 Redux-Form Field
中。但是当 HTML <input>
标签的值改变时 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)} />
)
}
每当输入 <input>
标签时,CustomInputComponent
的状态会成功更改,但上面包含 CustomInputComponent
的 Field
的值不会改变。我正在尝试通过以下方式访问 Field
的值:
const selector = formValueSelector('myForm')
let currentInput = selector(state, 'inputTextBox')
我希望 currentInput
包含在 input
中键入的当前值。我可能缺少什么?
几种方法:
- 将 Redux 表单 Field 的 data/methods 传递给 child(推荐——最低要求见下文) .
- 利用 React 状态,将其设置为 Redux 字段,然后从 parent 到 child.
https://codesandbox.io/s/z3xnjv4w7m(将 Redux 字段 data/methods 传递给 child) https://codesandbox.io/s/m4x7z7o429(通过 React state 控制 Redux Fields)
将 Redux 字段的 Data/Methods 传递给 Child 示例
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
需要从 parent 传递到 child。
Parent
<Field
component={CustomInputComponent}
name="inputTextBox"
/>
Child
export default ({ input: { onChange, value }}) => (
<input
type="text"
placeholder="Write something..."
className="uk-input"
onChange={onChange}
value={value}
/>
);
通过 React 状态控制字段
控制InputForm.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>
);