【问题标题】:How to use filter in that case? React在这种情况下如何使用过滤器?反应
【发布时间】:2020-05-27 08:09:56
【问题描述】:

有人可以帮助编写过滤我的搜索结果的函数吗? Sandobox中有代码:https://codesandbox.io/s/romantic-snowflake-irbhf?fontsize=14&hidenavigation=1&theme=dark

class Search extends React.Component {
  state = {
    searchValue: "",
    songs: [],
    musicTabs: ["Random", "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/.json?pattern=${searchInput}`;
    const response = await fetch(api_url);
    const songs = await response.json();
    this.setState({ songs });
  };

  render() {
    return (
      <div>
        <input
          name="text"
          type="search"
          placeholder="Wyszukaj..."
          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>
    </>
  );
};

我想按输入值和选定值进行搜索。例如,如果我输入任何标题或歌曲名称并选择低音,我想用歌曲/艺术​​家呈现结果,其中包括可用选项卡中的“低音”。如果将选择“随机”,那么它应该呈现所有结果。请帮帮我,我不知道该怎么做......

【问题讨论】:

  • 你想要像下面的Sandbox一样吗?这有点复杂,因为您的选项卡标识符与选择框中的字符串不匹配。如果代码对您有用,我可以添加一些解释以及如何改进代码的答案。
  • 是的,太棒了,非常感谢!

标签: javascript reactjs api methods filter


【解决方案1】:

实际上有多种方法可以执行此操作。例如,您可以将过滤后的歌曲置于状态,然后在渲染方法中映射它们,或者您可以在渲染方法中过滤它们,如下所示。

render() {
return (
  <div>
    <input
      name="text"
      type="search"
      placeholder="Wyszukaj..."
      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>
       //you can filter your songs here then map them
       //so whenever result or songs is changed this will 
        {this.state.songs.filter(s => this.state.result === 'Random' || s.tabTypes.includes(this.state.result.toUpperCase())).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>
);}

您可能需要根据值而不是输入名称来更新“结果”。您可以像这样设置输入的值:

<option value={value} name={name} key={index}> 

因此,当您向用户显示适当的名称时,您可以获得适当的密钥进行查询。

如果你卡在某个地方,请告诉我。我想我上面写的可以给你和想法。

【讨论】:

    【解决方案2】:

    这是一个简单的过滤器方法调用,用于根据所选的this.state.result 比较结果。它不适用于您的情况,因为您的下拉选择与 json 中返回的字符串不匹配。如果您希望使用此解决方案,则需要对过滤器进行一些修改,例如它适用于 "PLAYER""CHORDS""RANDOM",但不适用于 "TEXT_BASS_TAB""TEXT_GUITAR_TAB"它检查this.state.result 的文字字符串。也许键值映射,其中键是您的下拉选项,值是 json 等效项,这可能是一种可行的方式来完成这项工作。我还将您的歌曲值从 const 更改为 just be let,但这只是为了简化测试。这应该可以帮助您开始使用最适合您的解决方案。

    let songs = await response.json();
        if (this.state.result !== "Random" && this.state.result !== "") {
          songs = songs.filter(song =>
            song.tabTypes.includes(this.state.result.toUpperCase())
          );
        }
    this.setState({ songs });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 2011-04-16
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      相关资源
      最近更新 更多