将两个下拉过滤器连接到一个搜索按钮

时间:2018-05-11 02:40:29

标签: javascript reactjs filter dropdown

我有两个正在过滤的下拉列表,但是当您将其下拉并进行选择时,它们会进行过滤。我有一个搜索按钮,我想将它们都挂钩。因此,按下按钮后,您只看到一次结果更改。我想我拥有我需要的所有逻辑但是我不确定如何连接按钮 注意:我知道我在渲染中有很多逻辑,但我只是想让它先工作

到目前为止,这就是我所拥有的:

    constructor(props) {
        super(props);
        this.state = {
          developers: [],
          filterCountry: "All locations",
          filterSkills: "All skills"
        };
      }

      componentDidMount() {
        fetch('API')
        .then(features =>  features.json())
        .then(developers => {
          this.setState({  developers })   
        })
      }

      filterCountry(e){
        this.setState({filterCountry: e })
      }

      filterSkills(e){
        this.setState({filterSkills: e })
      }

      render() {

        let developers = this.state.developers.features   

        if (!developers ){
          return null
        }

        if (this.state.filterCountry && this.state.filterSkills) {
             developers = developers.filter( developer => { 
             return this.state.filterCountry === 'All locations' ||   
      developer.properties.continent.includes(this.state.filterCountry)
          });


             developers = developers.filter( developer => { 
             return this.state.filterSkills === 'All skills' || 
          developer.properties.skills.includes(this.state.filterSkills)
          });  
        }
   return (
         <div>
            <div>
              <ControlSelect
                onChange={this.filterCountry.bind(this)} 
                value={this.state.filterCountry}
                options={options_dd1}
              />
            </div>
            <div className="inline-block mr24">
              <ControlSelect
                onChange={this.filterSkills.bind(this)} 
                value={this.state.filterSkills}
                options={options_dd2}
              />
            </div>
            <button>Search</button>
          </div>
        <div>
          <div>
            {developers.map(developer => {
              return (
              <div key={developer.id}">
                {developer.properties.name}
                {developer.properties.description}
                {developer.properties.skills}
              </div>
          </div>
         </div>
       )}
    )}
)

任何帮助将不胜感激

1 个答案:

答案 0 :(得分:0)

你所遇到的主要问题是,一旦完成过滤,就无法获得原始的开发人员列表。您可以创建一个“原始列表”或开发人员以及一个新的filteredList,它可以被render方法实际用于显示数据。

基本上,在初始渲染中,状态中的developers键是从fetch加载的默认值,并将完整呈现。单击button后,doSearch方法将修改状态并删除开发人员。这将导致调用渲染并显示新的筛选列表。

否则,我在下面评论了一些小问题。

constructor(props) {
    super(props);
    this.state = {
      developers: [],
      filterCountry: "All locations",
      filterSkills: "All skills"
    };
  }

  componentDidMount() {
    fetch('API')
    .then(features =>  features.json())
    .then(developers => {
      this.setState({  developers })   
    })
  }

  filterCountry(e){
    this.setState({filterCountry: e })
  }

  filterSkills(e){
    this.setState({filterSkills: e })
  }

  doSearch() {
    // Create copy of state (you had a `.filtered` in your code, which doesn't make sense as developers is an array so it will have no `filtered` property unless you modified the prototype
    let developers = this.state.developers.slice()   

    // This if block is pointless, because you start with a default state in the constructor (so unless your ControlSelect have a falsy option, this will always evaluate to `true`)

    if (this.state.filterCountry && this.state.filterSkills) {
         // THis will match EITHER country OR skills. You can change to && if wanted.
         developers = developers.filter( developer => { 
         return this.state.filterCountry === 'All locations' ||   
  developer.properties.continent.includes(this.state.filterCountry) || this.state.filterSkills === 'All skills'
  || developer.properties.skills.includes(this.state.filterSkills)
      });
    this.setState({ developers })
    }
  }

  render() {
return (
     <div>
        <div>
          <ControlSelect
            onChange={this.filterCountry.bind(this)} 
            value={this.state.filterCountry}
            options={options_dd1}
            value={this.state.filterCountry}
          />
        </div>
        <div className="inline-block mr24">
          <ControlSelect
            onChange={this.filterSkills.bind(this)} 
            value={this.state.filterSkills}
            options={options_dd2}
            value={this.state.filterSkills}
          />
        </div>
        <button onClick={this.doSearch.bind(this)}>Search</button>
      </div>
    <div>
      <div>
        {/* Now the developers contains stuff that was filtered in search */}
        {this.state.developers.map(developer => {
          return (
          <div key={developer.id}>
            {developer.properties.name}
            {developer.properties.description}
            {developer.properties.skills}
          </div>
      </div>
     </div>
   )}
)}
)