我正在尝试在React中设计一个可输入类型的输入组件,该组件包装在Redux-Form Field
中。但是,当HTML Field
标签的值更改时,<input>
的值不会更新。
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
的状态都会成功更改,但是包含Field
的上方CustomInputComponent
的值不会更改。我正在尝试通过以下方式访问Field
的值:
const selector = formValueSelector('myForm')
let currentInput = selector(state, 'inputTextBox')
我希望currentInput
包含在input
内键入的当前值。我可能会缺少什么?
答案 0 :(得分:1)
几种方法:
https://codesandbox.io/s/z3xnjv4w7m(将Redux Field数据/方法传递给子级) https://codesandbox.io/s/m4x7z7o429(通过React状态控制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>
);