Как получить значение опции выбора - PullRequest
0 голосов
/ 10 февраля 2020

Мне нужна небольшая помощь с моим проектом. Я думаю, что это почти сделано, но я не знаю, как закончить sh ...

Итак, я хочу создать приложение с вводом, выбором и кнопкой. На вход вы можете написать, например, mettalica и после нажатия на кнопку приложение отображает список со всеми песнями, названиями и tabTypes (гитарные вкладки). Проблема в том, что я хочу получать информацию из select и рендерить только те песни, которые включают, например, вкладки проигрывателя.

Код песочницы: https://codesandbox.io/s/react-example-ys6py?fontsize=14&hidenavigation=1&theme=dark

class Search extends React.Component {
  state = {
    searchValue: "",
    songs: [],
    musicTabs: [
      'Dowolne',
      'Bass',
      'Player',
      'Chords',
      'Guitar'
    ],
    result: ''
  };

  handleOnChange = event => {
    this.setState({ searchValue: event.target.value });
  };

  handleSelectChange = (event) => {
    this.setState({
      result: event.target.value
    })
    console.log(this.state.result)
  }

  handleSearch = () => {
    this.makeApiCall(this.state.searchValue);
  };

  makeApiCall = async searchInput => {
    let api_url = `https://www.songsterr.com/a/ra/songs/byartists.json?artists=${searchInput}`;
    const response = await fetch(api_url);
    const songs = await response.json();
    this.setState({ songs });
  };

  render() {
    return (
      <div>
        <Header />
        <input
          name="text"
          type="search"
          placeholder="Search..."
          onChange={event => this.handleOnChange(event)}
          value={this.state.SearchValue}
        />

        <Select optionValue={ this.state.musicTabs } change={ this.handleSelectChange } value={ this.state.result } />

        <br />
        <button onClick={this.handleSearch}>Search</button>


        {this.state.songs ? (
          <div>
            {
              this.state.songs.map((song, index) => (
                <div key={index} className="lists">
                  <h1>Artist: <span>{song.artist.name}</span></h1>
                  <h2>Song title: <span>{song.title}</span></h2>
                  <ol>
                    <b>Available tabs:</b>
                    {song.tabTypes.map((tab, index) =>
                      <li key={index}> {song.tabTypes[index]} </li>
                    )}

                  </ol>

                </div>
              ))


            }
          </div>
        ) : (
            <p>Something</p>
          )}
      </div>
    );
  }
}



const Select = (props) => {
  const { optionValue, change } = props;

  const valueMusicTabs = optionValue.map((musicTab, index) => {
   return <option name={ optionValue[index] } key={ index }> { optionValue[index] } </option>
  })

  return (

    <>
    <select onChange={ change }>
      { valueMusicTabs } 

    </select>

  </>

  )
};

Спасибо за помощь, ребята!

Ответы [ 4 ]

1 голос
/ 10 февраля 2020

Я думаю, что вы все сделали правильно, просто неправильно использовали prop

<Select optionValue={ this.state.musicTabs } onChange={ this.handleSelectChange } value={ this.state.result } />

change реквизит для компонента Select следует просто изменить на onChange, так как это событие по умолчанию оно будет передано вместе с событием вашему handleChange методу

0 голосов
/ 10 февраля 2020

Спасибо за ответы! У меня последний вопрос, где я должен использовать метод для фильтрации этого списка. Если я выберу «Player», я хочу рендерить только те песни, которые включают вкладку «Player» в tabTypes. Я до сих пор не могу получить это. Я не могу сделать это, изменив ссылку API.

0 голосов
/ 10 февраля 2020

Если я правильно понимаю. Вы хотите получить результаты из API на основе выбранных значений input и select.

, поскольку, как я вижу, вы только передаете параметр из input ничего из select.

  handleSearch = () => {
    this.makeApiCall(this.state.searchValue);
  };

  makeApiCall = async searchInput => {
    let api_url = `https://www.songsterr.com/a/ra/songs/byartists.json?artists=${searchInput}`;
    const response = await fetch(api_url);
    const songs = await response.json();
    this.setState({ songs });
  };

Новый вызов будет

let api_url = `https://www.songsterr.com/a/ra/songs/byartists.json?artists=${searchInput}&tabTypes=${selectValue}`; 

Я не знаю, какие параметры принимает этот API.

0 голосов
/ 10 февраля 2020

Я проверил коды и окно, все работало правильно. this.setState - асинхронная функция. Таким образом, если вы будете console.log после this.setState шансов, вы не будете регистрировать обновленное значение. Вы можете сделать это с помощью функции обратного вызова.

handleSelectChange = (event) => {
    this.setState({
      result: event.target.value
    }, () => console.log(this.state.result))
  }

Если вы хотите filter, вы можете сделать это, сделав такую ​​функцию:

filterSongs = selected => {
 return songs.filter(song => song.tabTypes === selected);
}

и после этого измените ваш handleSelectChange как:

handleSelectChange = (event) => {
    let songs = filterSongs(event.target.value);
    this.setState({
      result: event.target.value,
      toDisplay: songs
    }, () => console.log(this.state.result))
  }

и, наконец, в вашем JSX:

return (
  <>
    {toDisplay.map((song, index) => {
      return <p key={index}>{song.toString()}</p>
    })}
  </>
);
...