Отобразить отфильтрованный массив в React - PullRequest
0 голосов
/ 14 ноября 2018

Я сделал компонент, содержащий два выпадающих списка.Опции во втором раскрывающемся меню должны быть отфильтрованы в зависимости от выбранной опции из первого раскрывающегося меню.

Теперь я хочу отобразить отфильтрованный массив, который хранится в const, аналогично тому, как я сопоставляю options1:

render() {

const options1 = [
   {value: 'one', label: 'One'},
   {value: 'two', label: 'Two'}
];



const options2 = [
   {value: 'one-a', label: 'One A', link: 'one'},
   {value: 'one-b', label: 'One B', link: 'one'},
   {value: 'two-a', label: 'Two A', link: 'two'},
   {value: 'two-b', label: 'Two B', link: 'two'}
];

const filteredOptions = options2.filter(o => o.link === this.state.selectedOption.value);

return (
<div style={style}>
   <div>
      <label>Select one</label>
      <select 
         value={this.state.selectedOption.value} 
         onChange={this.handleChange1} 
      >
         {options1.map(tag => <option>{tag.value}</option>)}
      </select>

   </div>
   <div>
      <label>Then the other</label>
      <select
         value={this.state.selectedOption2.value}
         onChange={this.handleChange2}
      >
         {filteredOptions.map(tag => <option>{tag.value}</option>)}
      </select>

   </div>
</div>
)
}

Первое отображение options1 работает просто отлично.Тем не менее, мой тег выбора становится пустым для сопоставления filterOptions.

Я понятия не имею, почему он не будет работать.У кого-нибудь есть идея?

Полный код: https://www.codepile.net/pile/evNqergA

Ответы [ 3 ]

0 голосов
/ 14 ноября 2018

Лучший способ сделать это - не использовать метод рендеринга.

1) переместите ваши массивы в состояние или другие члены экземпляра 2) убедитесь, что сортировка запускается только один раз

this.setState(lastState => ({
  ...lastState,
  options2: lastState.options2.filter(yourFilterFn)
}))

3) отобразить отфильтрованный массив в JSX внутри вашего метода визуализации

Примечание: здесь используется неизменяемый setState (что, как я понимаю, важно, если вы создадите новый фильтрованный массив из options2 в вашем примере). Если вы хотите следовать еще более функциональному шаблону, вы можете выполнить фильтрацию внутри вашего метода рендеринга (хотя я не рекомендую его). Если вы решили отфильтровать внутри вашего метода рендеринга, рассмотрите возможность использования техники запоминания из React 16.7 (которая в настоящее время находится в Alpha).

0 голосов
/ 14 ноября 2018

Вот рабочий пример того, что вы пытаетесь сделать.

import React, { Component } from "react";

const options1 = [
  { value: "one", label: "One" },
  { value: "two", label: "Two" }
];

const options2 = [
  { value: "one-a", label: "One A", link: "one" },
  { value: "one-b", label: "One B", link: "one" },
  { value: "two-a", label: "Two A", link: "two" },
  { value: "two-b", label: "Two B", link: "two" }
];

export default class SelectsComponent extends Component {
  handleChange1 = e => {
    console.log(e);
    this.setState({
      selectedOption: { value: e.target.value }
    });
  };

  handleChange2 = e => {
    this.setState({
      selectedOption2: { value: e.target.value }
    });
  };

  constructor(props) {
    super(props);
    this.state = {
      selectedOption: { value: "one" },
      selectedOption2: { value: "one-a" }
    };
  }

  render() {
    const filteredOptions = options2.filter(
      o => o.link === this.state.selectedOption.value
    );

    return (
      <div>
        <div>
          <label>Select one</label>
          <select
            value={this.state.selectedOption.value}
            onChange={this.handleChange1}
          >
            {options1.map(tag => (
              <option>{tag.value}</option>
            ))}
          </select>
        </div>
        <div>
          <label>Then the other</label>
          <select
            value={this.state.selectedOption2.value}
            onChange={this.handleChange2}
          >
            {filteredOptions.map(tag => (
              <option>{tag.value}</option>
            ))}
          </select>
        </div>
      </div>
    );
  }
}
0 голосов
/ 14 ноября 2018

В вашем сценарии filteredOptions будет пустым массивом.

Проверка на o.link === this.state.selectedOption.value делает что-то не так.

Проверьте значение this.state.selectedOption.value, оно установлено неправильно.

...