Невозможно распространить пользовательское значение Select в состояние его родительского компонента - PullRequest
0 голосов
/ 25 апреля 2019

У меня есть базовое приложение ReactJS, которое содержит пользовательский Select, который заполняется через 2 секунды.

. / Src / controls / Select / Select.js

import React, { Component } from 'react';
import './Select.scss';

class Select extends Component {

  constructor(props) {
    super(props);
    let { name, value, data, className, onChange, onFocus, onBlur, ...controlProps } = this.props;
    this.name = name;
    this.onChange = onChange || ((e) => { });
    this.onFocus = onFocus || ((e) => { });
    this.onBlur = onBlur || ((e) => { });
    this.controlProps = controlProps;
    this.state = {
      [name]: value,
      className,
    };
  }

  componentDidMount() {
    this.handleChange({ target: this.refs.select });
  }

  handleChange = (e) => {
    let target = e.target;
    let name = target.name;
    let value = target.value;
    this.setState({
      [name]: value,
    });
    this.onChange(e);
  };

  render() {
    let data = this.props.data || [];
    return (
      <div className="control-select" {...this.controlProps}>
        <div className="custom-dropdown custom-dropdown--grey">
          <select
            ref="select"
            name={this.name}
            className="custom-dropdown__select custom-dropdown__select--grey"
            value={this.state[this.name]}
            onChange={this.handleChange}
          >
            {
              data.map((elem, index) => {
                return <option value={elem.value} key={index}>{elem.text}</option>
              })
            }
          </select>
        </div>
      </div>
    );
  }

}

export default Select;

Также у меня есть основной App:

. / Src / index.js

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import Select from './controls/Select/Select';
import './styles.scss';

export default class Lab extends Component {

    constructor(props) {
    super(props);
    this.state = {
      selection: '',
      options: [],
    }
    setTimeout(() => {
      this.setState({
        options: [
          { "value": "option_01", "text": "Option 01" },
          { "value": "option_02", "text": "Option 02" },
          { "value": "option_03", "text": "Option 03" },
          { "value": "option_04", "text": "Option 04" },
          { "value": "option_05", "text": "Option 05" },
        ],
      });
    }, 2000);
  }

  handleChange = (e) => {
    let target = e.target;
    let name = target.name;
    let value = target.value;
    this.setState({
      [name]: value,
    });
  };

    render() {
        return (
            <div className="App">
        <div style={{ borderBottom: '1px solid #ddd', margin: '20px 0 10px 0' }}>
          The value on the select box should appear on the yellow box automatically.
        </div>
                {/* BEGIN OF WORKING AREA */}
        <table style={{ display: 'inline-block', margin: '0 0 10px', border: 'none' }}>
          <tbody>
            <tr>
              <td style={{ width: '218px', border: 'none' }}>
                <Select
                  name="selection"
                  value={this.state.selection}
                  data={ this.state.options.map(elem => { return { value: elem.value, text: elem.text }; }) }
                  style={{ width: '100%' }}
                  onChange={ this.handleChange }
                />
              </td>
              <td style={{ width: '100px', border: 'none', color: '#b00', backgroundColor: '#ffa', textAlign: 'center', fontSize: '14px' }}>
                <span>{this.state.selection}</span>
              </td>
            </tr>
          </tbody>
        </table>
        {/* END OF WORKING AREA */}
            </div>
        );
    }
}

if (document.getElementById('root')) {
    ReactDOM.render(<Lab />, document.getElementById('root'));
}

Что мне нужно, так это, который сразу после заполнения пользовательского Select распространяет свое значение на родительский компонент state.Прямо сейчас, когда он заполняется, он этого не делает (вы можете проверить это с помощью пустой желтой рамки).С другой стороны, если вы измените параметр для этого Select, то его значение будет успешно распространено.

Здесь у вас есть Codesandbox.io, с которым вы можете играть:

https://codesandbox.io/s/73z220z11q

Если возможно, пожалуйста, верните раздвоенный Codesandbox.io с вашим решением.

Вот что я хочу сделать:

enter image description here

[ОБНОВЛЕНИЕ]

Здесь у вас есть реальный код, который меня беспокоит:

https://codesandbox.io/s/xl6zxz0v84

ЕслиПользователь вручную выбирает параметр на Select, затем это значение правильно устанавливается как selectedTheme (в состоянии приложения).С этой частью все в порядке.

То, что я хочу, это , если пользователь ничего не выбирает вручную, тогда значение, отображаемое в списке выбора, должно быть установлено как selectedTheme.В настоящее время установлено значение «ничего» (если пользователь не взаимодействует).

Вы можете проверить значение selectedTheme, нажав кнопку Submit.

Спасибо!

Ответы [ 2 ]

0 голосов
/ 25 апреля 2019

Привет, ошибка в том, что элемент выбора устанавливает только выбор при срабатывании функции onChange.

если вы хотите, в то время как население необходимо установить вручную или установить значение по умолчанию в состоянии выбора.

 //set the selection default state at the time of setting options in constructor.
 constructor(props) {
    super(props);
    this.state = {
      selection: "",
      options: []
    };
    setTimeout(() => {
      this.setState(
        {
          options: [
            { value: "option_01", text: "Option 01" },
            { value: "option_02", text: "Option 02" },
            { value: "option_03", text: "Option 03" },
            { value: "option_04", text: "Option 04" },
            { value: "option_05", text: "Option 05" }
          ]
        },
        () => this.setState({ selection: this.state.options[0].value })
      );
    }, 2000);
  }

Демонстрационная ссылка

0 голосов
/ 25 апреля 2019

Я думаю, что проблема в том, как вы звоните handleChange напрямую из componentDidMount вашего пользовательского выбора .. В то время ваш target на самом деле не имеет value, потому что вы устанавливаем параметры на основе состояния Redux.

Чтобы решить эту проблему, вы можете использовать componentWillReceiveProps в своем компоненте, где вы получаете опции от Redux, и изменить state.selection вручную, когда вы получаете обновления. Как это:

componentWillReceiveProps(nextProps) {
  if (this.props.options.length !== nextProps.options.length) {
    this.setState({ selection: nextProps.options[0].value });
  }
}

Вот раздвоенная + обновленная песочница

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