Пользовательский компонент Dropdown Field не совместим с Redux-Form - PullRequest
0 голосов
/ 26 сентября 2018

У меня следующая проблема.Я настроил свой собственный компонент 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;

Ответы [ 2 ]

0 голосов
/ 29 сентября 2018

redux-form работает только с «контролируемыми» компонентами.Это означает, что компоненту нужна опора, которую родитель использует, чтобы сказать ему, какова его ценность.Например, следующее является контролируемым компонентом:

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

Обратите внимание, что мы сообщаем компоненту TextField, каково его значение.Вы должны изменить свой компонент, чтобы работать так же.Единственное предостережение здесь заключается в том, что в форме приставки вводится реквизит с именем input, который представляет собой объект, содержащий value и onChange (и несколько других вещей), вместо непосредственного введения value и onChange.

Таким образом, для примера выше, он должен работать так, чтобы поддерживать redux-form:

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

Вот ваш компонент, написанный как «контролируемый» компонент, способ, который должен работать с избыточностью-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-формой вы можете просто сделать следующее, так как redux-form управляет всемиэто для вас:

<Field
  component={MyCustomizedDropdown}
/>
0 голосов
/ 28 сентября 2018

Вы не должны обрабатывать значение ввода в состоянии ввода.MyCustomizedDropDown должен получить функцию handleChange, items и selectedItem в качестве реквизита.Единственное, что должно быть в состоянии компонента - это открыто оно или нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...