簡體   English   中英

自定義下拉字段組件與Redux-Form不兼容

[英]Customized Dropdown Field Component not compatible with Redux-Form

我有以下問題。 我使用元素自定義了自己的DropDown組件。 我希望該元素與Redux-Form交互,因為我要保存所選的值。 這不起作用:

<Field
name="name"
component={MyCustomizedDropDown}
data={myData}/>

另一種選擇是使用“輸入”道具,但是由於我正在使用元素,因此這是不可能的。 有人可以給我解決方案嗎? 謝謝。

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函數, itemsselectedItem作為道具。 組件狀態下唯一的事情就是它是否打開。

redux-form僅適用於“受控”組件。 這意味着組件需要一個道具,父母可以使用它來告知其價值。 例如,以下是受控組件:

<TextField 
  value={this.state.inputValue} 
  onChange={(value) => this.setState({ inputValue: value })} 
/>

請注意,我們要告訴TextField組件其值是什么。 您需要更改組件以相同的方式工作。 唯一需要注意的是,redux-form會注入一個稱為input的prop,它是一個包含valueonChange (以及其他一些東西)的對象,而不是直接注入valueonChange

因此,對於上面的示例,它需要像這樣工作以支持redux-form

<TextField 
  input={{
    value: this.state.inputValue,
    onChange: (value) => this.setState({ inputValue: value })
  }}
/>

這是將您的組件編寫為“受控”組件的方式,該方式應與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;
  • 請注意,我們使用this.props.input.value告訴MyCustomizedDropdown它的值是this.props.input.value
  • 如果組件想要更改其值,我們將其稱為this.props.input.onChange 由於它不能獨自完成它,因此需要告訴它要更改其值的父項。
  • 父級需要響應onChange並更新MyCustomizedDropdown的值

例如,這是不帶redux-form組件的使用redux-form

<MyCustomizedDropdown 
  input={{
    value: this.state.dropDownValue,
    onChange: (value) => this.setState({ dropDownValue: value })
  }}
/>

使用redux-form,您可以簡單地執行以下操作,因為redux-form可為您管理所有這些工作:

<Field
  component={MyCustomizedDropdown}
/>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM