【问题标题】:Connect two dropdown filters to one search button将两个下拉过滤器连接到一个搜索按钮
【发布时间】:2018-10-21 09:27:02
【问题描述】:

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

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

    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>
       )}
    )}
)

任何帮助将不胜感激

【问题讨论】:

  • 你为什么不能把这个逻辑添加到onClickbutton 中?
  • 这部分我有点困惑.. 我不知道如何构建 onclick
  • 更多关于你的代码发生了什么的细节会有所帮助。这些ControlSelect 组件是什么?它们的代码在哪里? .includes() 是什么?
  • 控件选择只是生成下拉菜单(这些组件的代码并不是真正需要解决按钮问题)..,并且includes是一个javascript方法,用于确定数组是否包含某个元素,

标签: javascript reactjs filter dropdown


【解决方案1】:

您所拥有的主要问题是,一旦过滤完成,就无法恢复原始开发人员列表。您可以创建一个“原始列表”或开发人员和一个新的filteredList,它实际上可以被渲染方法用来显示数据。

基本上,在您的初始渲染中,您状态中的 developers 键是从 fetch 加载的默认值,并将完整地渲染。一旦点击buttondoSearch 方法将修改状态并移除开发者。这将导致调用渲染并显示新的过滤列表。

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

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>
   )}
)}
)

【讨论】:

  • 这绝对看起来应该可以工作,但我得到“this.state.developers.map is not a function”错误
  • this.state.developers 上做一个console.log 看看它是什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多