使用React筛选对象列表

7

这可能是一个克隆帖子,但我在我的情况下没有找到任何解决方案。我有一组对象:

export default function() {
  return [
    {name: 'Mark Teer Stegen'},
    {name: 'Nelson Semedo'},
    {name: 'Gerrard Pique'},
    {name: 'Ivan Rakitic'},
    {name: 'Sergio Busquets'},
    {name: 'Denis Suarez'},
    {name: 'Coutinho'},
    {name: 'Luis Suarez'},
    {name: 'Lionel Messi'},
    {name: 'Dembele'},
    {name: 'Malcom'}
  ]
}

我将其导入到组件中,赋值给状态并在下面的组件中显示。
import React, {Component} from 'react';
import {connect} from 'react-redux';

class Barca extends Component{
  constructor(props){
    super(props);

    this.state = {
      players: this.props.players,
      player: '' //empty to set as an input
    }
  }

  onChange(e){
    this.setState({
      player: e.target.value
    });
    console.log(this.state.player);
  }
  renderList(){
    return this.state.players.map((player) => {
      return(
        <tr key={player.name}>
          <td>{player.name}</td>
        </tr>
      );
    });
  }
  render(){
    return(
      <div className="col-sm-6 table-col table-responsive">
        <input
          type="text"
          value={this.state.player}
          onChange={this.onChange.bind(this)}
        />
        <table className="table table-striped">
          <thead>
            <tr>
              <th className="text-center">
                FC Barcelona
              </th>
            </tr>
          </thead>
          <tbody>
            {this.renderList()}
          </tbody>
        </table>
      </div>
    );
  }
}

const mapStateToProps = (state) => {
  return {
    players: state.reducerBarca
   };
};


export default connect(mapStateToProps)(Barca);

列表看起来像这样

列表视图

问题在于我想根据输入值过滤我的玩家列表。我在这里进行了一些研究,我只发现可以在数组中过滤,而不是像对象列表中那样。

我现在所做的:

  1. 显示玩家列表
  2. 获取输入框中的值,并在每次输入后显示它
  3. 如何通过输入的条件渲染我的列表?

感谢大家!我已删除了玩家状态

constructor(props){
    super(props);

    this.state = {
      //players: this.props.players <-- Stupid thing
      player: '' //empty to set as an input
    }
  }

并且重写我的renderList()函数

return this.props.players.filter(player =>
        player.name.toLowerCase().includes(this.state.player.toLowerCase())).map(searchedPlayers => {
          return(
            <tr key={searchedPlayers.name}>
              <td>{searchedPlayers.name}</td>
            </tr>
          );
        })
    }

1
你为什么要将Redux状态复制到本地状态? - azium
另外,你没有在任何地方调用.filter - azium
  1. 我认为在React状态中过滤列表会更容易。
  2. 我试图使用.filter,但出现了错误。
- Paweł Stanecki
不,这会让它更难...如果你只是调用this.props.players.filter,你根本不需要任何本地状态...你甚至不需要使用组件类,只需使用一个函数。 - azium
1
...而这是一个数组 - xadm
setState 是异步的,不能在写入后立即读取 - 请阅读文档...如果确实需要,请使用回调函数。 - xadm
3个回答

10
this.state.players.filter(player => player.name.includes(this.state.player))

如果你想把它们映射而不仅仅是过滤状态...

this.state.players.filter(player => 
player.name.includes(this.state.player)).map(searchedPlayers => {
  return(
    <tr key={searchedPlayers.name}>
      <td>{searchedPlayers.name}</td>
    </tr>
  );
})
请注意,您也可以直接从props中呈现而不设置为状态(以避免每次用户输入时重新呈现),方法是替换


Note: 您还可以从props直接呈现内容,而无需将其设置为state(以避免在用户输入时进行重新呈现),方法是替换

this.state.players

this.props.players

1
这个答案很好。如果提到没有必要将redux状态复制到本地状态中,那就更好了。 - azium
将“INSERTUSERSEARCHHERE”更改为“this.state.player”-它已被正确使用/设置。 - xadm

2

您可以使用过滤器:

renderList(){
    const { player } = this.state
    const { players } = this.props
    // ignore user's typing case
    const iPlayer = player.toLowerCase()
    const filteredPlayers = players.filter(p => 
       p.name.toLowerCase().includes(iPlayer)
    )
    // now, map to the filteredPlayers

0

你不需要使用复制状态到属性,你也可以使用this.props.players

getPlayers() {
  if(this.state.player) {
    return this.state.players.filter(player => player.name.includes(this.state.player))
  } else {
    return this.state.players
  }
}

然后您可以调用 let collection = getPlayers(); 并将玩家映射到 HTML 内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接