自定义下拉字段组件与 Redux-Form 不兼容
Customized Dropdown Field Component not compatible with Redux-Form
我有以下问题。
我使用元素自定义了我自己的 DropDown 组件。
我希望此元素与 Redux-Form 交互,因为我想保存所选的值。
这不起作用:
<Field
name="name"
component={MyCustomizedDropDown}
data={myData}/>
另一种选择是使用 "input" 道具,但由于我使用的是元素,所以这是不可能的。
有人可以给我一个解决方案吗?谢谢
MyCustomizedDropDown 组件:
import React, { Component } from "react";
import PropTypes from "prop-types";
class MyCustomizedDropdown extends Component {
constructor(props) {
super(props);
this.state = {
...this.props,
items: this.props.items || [],
selectedItem: this.props.items[0] || this.props.selectedItem,
showItems: false,
isOpened: false
};
this.dropDown = this.dropDown.bind(this);
this.selectedItem = this.selectedItem.bind(this);
}
dropDown() {
this.setState(prevState => ({
showItems: !prevState.showItems
}));
}
selectedItem(item) {
this.setState({
selectedItem: item,
showItems: false
});
}
render() {
const { input } = this.props;
return (
<div className="select-box--wrapper">
<div className="select-box--toggle" onClick={this.dropDown}>
<div className="select-box--selected-item">
{this.state.selectedItem && this.state.selectedItem.value}
</div>
<MyImage
className={`${
this.state.showItems
? "select-box--arrow-rotated"
: "select-box--arrow"
}`}
/>
</div>
<div className="select-box--main">
<div
{...input} \THIS DOES NOT WORK
className="select-box--items">
{this.state.data.map(item => (
<div key={item.id} onClick={() => this.selectedItem(item)}>
{item.value}
</div>
))}
</div>
</div>
</div>
);
}
}
MyCustomizedDropdown.propTypes = {
data: PropTypes.array,
selectedItem: PropTypes.array,
input: PropTypes.object
};
export default MyCustomizedDropdown;
您不应该在输入状态下处理输入值。 MyCustomizedDropDown
应该接收 handleChange
函数,items
和 selectedItem
作为属性。唯一应该处于组件状态的是它是否打开。
redux-form 仅适用于 "controlled" 组件。这意味着该组件需要一个父级用来告诉它它的值是什么的道具。比如下面是一个受控组件:
<TextField
value={this.state.inputValue}
onChange={(value) => this.setState({ inputValue: value })}
/>
请注意,我们告诉 TextField
组件它的值是什么。您需要更改组件才能以相同的方式工作。这里唯一需要注意的是,redux-form 注入了一个名为 input
的 prop,它是一个包含 value
和 onChange
(以及其他一些东西)的对象,而不是直接注入 value
和 onChange
.
所以对于上面的例子,它需要这样工作才能支持redux-form
:
<TextField
input={{
value: this.state.inputValue,
onChange: (value) => this.setState({ inputValue: value })
}}
/>
这是你的组件,写成 "controlled" 组件,以一种应该与 redux-form 一起工作的方式:
import React, { Component } from "react";
import PropTypes from "prop-types";
class MyCustomizedDropdown extends Component {
constructor(props) {
super(props);
this.state = {
showItems: false
};
this.dropDown = this.dropDown.bind(this);
this.selectedItem = this.selectedItem.bind(this);
}
dropDown() {
this.setState(prevState => ({
showItems: !prevState.showItems
}));
}
hideDropdownItems() {
this.setState({
showItems: false
});
}
render() {
const { input } = this.props;
return (
<div className="select-box--wrapper">
<div className="select-box--toggle" onClick={this.dropDown}>
<div className="select-box--selected-item">
{this.input.value && this.input.value.value}
</div>
<MyImage
className={`${
this.state.showItems
? "select-box--arrow-rotated"
: "select-box--arrow"
}`}
/>
</div>
<div className="select-box--main">
<div
className="select-box--items">
{this.state.data.map(item => (
<div
key={item.id}
onClick={() => {
this.input.onChange(item)
this.hideDropdownItems();
}}
>
{item.value}
</div>
))}
</div>
</div>
</div>
);
}
}
MyCustomizedDropdown.propTypes = {
data: PropTypes.array,
selectedItem: PropTypes.array,
input: PropTypes.object
};
export default MyCustomizedDropdown;
- 请注意,我们告诉
MyCustomizedDropdown
它的价值在使用 this.props.input.value
- 如果组件想要更改它的值,我们会调用
this.props.input.onChange
。由于它不能自己完成,它需要告诉它的父级它想要更改值。
- 家长需要回应
onChange
并更新MyCustomizedDropdown
的值
例如,如果没有 redux-form
:
,这就是您使用组件的方式
<MyCustomizedDropdown
input={{
value: this.state.dropDownValue,
onChange: (value) => this.setState({ dropDownValue: value })
}}
/>
使用 redux-form,您只需执行以下操作,因为 redux-form 会为您管理所有这些内容:
<Field
component={MyCustomizedDropdown}
/>
我有以下问题。 我使用元素自定义了我自己的 DropDown 组件。 我希望此元素与 Redux-Form 交互,因为我想保存所选的值。 这不起作用:
<Field
name="name"
component={MyCustomizedDropDown}
data={myData}/>
另一种选择是使用 "input" 道具,但由于我使用的是元素,所以这是不可能的。 有人可以给我一个解决方案吗?谢谢
MyCustomizedDropDown 组件:
import React, { Component } from "react";
import PropTypes from "prop-types";
class MyCustomizedDropdown extends Component {
constructor(props) {
super(props);
this.state = {
...this.props,
items: this.props.items || [],
selectedItem: this.props.items[0] || this.props.selectedItem,
showItems: false,
isOpened: false
};
this.dropDown = this.dropDown.bind(this);
this.selectedItem = this.selectedItem.bind(this);
}
dropDown() {
this.setState(prevState => ({
showItems: !prevState.showItems
}));
}
selectedItem(item) {
this.setState({
selectedItem: item,
showItems: false
});
}
render() {
const { input } = this.props;
return (
<div className="select-box--wrapper">
<div className="select-box--toggle" onClick={this.dropDown}>
<div className="select-box--selected-item">
{this.state.selectedItem && this.state.selectedItem.value}
</div>
<MyImage
className={`${
this.state.showItems
? "select-box--arrow-rotated"
: "select-box--arrow"
}`}
/>
</div>
<div className="select-box--main">
<div
{...input} \THIS DOES NOT WORK
className="select-box--items">
{this.state.data.map(item => (
<div key={item.id} onClick={() => this.selectedItem(item)}>
{item.value}
</div>
))}
</div>
</div>
</div>
);
}
}
MyCustomizedDropdown.propTypes = {
data: PropTypes.array,
selectedItem: PropTypes.array,
input: PropTypes.object
};
export default MyCustomizedDropdown;
您不应该在输入状态下处理输入值。 MyCustomizedDropDown
应该接收 handleChange
函数,items
和 selectedItem
作为属性。唯一应该处于组件状态的是它是否打开。
redux-form 仅适用于 "controlled" 组件。这意味着该组件需要一个父级用来告诉它它的值是什么的道具。比如下面是一个受控组件:
<TextField
value={this.state.inputValue}
onChange={(value) => this.setState({ inputValue: value })}
/>
请注意,我们告诉 TextField
组件它的值是什么。您需要更改组件才能以相同的方式工作。这里唯一需要注意的是,redux-form 注入了一个名为 input
的 prop,它是一个包含 value
和 onChange
(以及其他一些东西)的对象,而不是直接注入 value
和 onChange
.
所以对于上面的例子,它需要这样工作才能支持redux-form
:
<TextField
input={{
value: this.state.inputValue,
onChange: (value) => this.setState({ inputValue: value })
}}
/>
这是你的组件,写成 "controlled" 组件,以一种应该与 redux-form 一起工作的方式:
import React, { Component } from "react";
import PropTypes from "prop-types";
class MyCustomizedDropdown extends Component {
constructor(props) {
super(props);
this.state = {
showItems: false
};
this.dropDown = this.dropDown.bind(this);
this.selectedItem = this.selectedItem.bind(this);
}
dropDown() {
this.setState(prevState => ({
showItems: !prevState.showItems
}));
}
hideDropdownItems() {
this.setState({
showItems: false
});
}
render() {
const { input } = this.props;
return (
<div className="select-box--wrapper">
<div className="select-box--toggle" onClick={this.dropDown}>
<div className="select-box--selected-item">
{this.input.value && this.input.value.value}
</div>
<MyImage
className={`${
this.state.showItems
? "select-box--arrow-rotated"
: "select-box--arrow"
}`}
/>
</div>
<div className="select-box--main">
<div
className="select-box--items">
{this.state.data.map(item => (
<div
key={item.id}
onClick={() => {
this.input.onChange(item)
this.hideDropdownItems();
}}
>
{item.value}
</div>
))}
</div>
</div>
</div>
);
}
}
MyCustomizedDropdown.propTypes = {
data: PropTypes.array,
selectedItem: PropTypes.array,
input: PropTypes.object
};
export default MyCustomizedDropdown;
- 请注意,我们告诉
MyCustomizedDropdown
它的价值在使用this.props.input.value
- 如果组件想要更改它的值,我们会调用
this.props.input.onChange
。由于它不能自己完成,它需要告诉它的父级它想要更改值。 - 家长需要回应
onChange
并更新MyCustomizedDropdown
的值
例如,如果没有 redux-form
:
<MyCustomizedDropdown
input={{
value: this.state.dropDownValue,
onChange: (value) => this.setState({ dropDownValue: value })
}}
/>
使用 redux-form,您只需执行以下操作,因为 redux-form 会为您管理所有这些内容:
<Field
component={MyCustomizedDropdown}
/>