7

It could be a clone post but I did not find any solution for in my case. I have list of an objects:

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'}
  ]
}

I import it to the component, assign to the state and displaying it in the component below.

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

List looks like that

list view

The problem is that I would like to filter my players list by the value from input. I have done some research here and I have only found filtering in Array, not like I have in Objects list.

What I have done for now:

  1. displaying the players list
  2. Geting the value from the input and displaying it after every written letter
  3. How to render my list by the inputted term ???

Thank you all people ! I have removed the players state

constructor(props){
    super(props);

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

and rewrite my renderList() function

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>
          );
        })
    }
6
  • 1
    why are you copying the redux state to local state? Commented Aug 17, 2018 at 18:41
  • also, you're not calling .filter anywhere Commented Aug 17, 2018 at 18:44
  • 1. I thought that it would be easier to filter the list in React state. 2. I was trying to put .filter but an error ocurred then Commented Aug 17, 2018 at 18:45
  • no it makes it harder... if you just call this.props.players.filter you don't need any local state at all.. you don't even need to use a component class just use a function Commented Aug 17, 2018 at 18:46
  • 1
    ... and this is an array Commented Aug 17, 2018 at 18:46

3 Answers 3

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

And if you wanted to then map them instead of just filtering the state...

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

Note you can also render straight from props without setting to state, (to avoid re-renders every-time the user types) by replacing

this.state.players

with

this.props.players
Sign up to request clarification or add additional context in comments.

2 Comments

this answer if fine. It would be even better if mentioned that there's no reason to duplicate redux state into local state
change INSERTUSERSEARCHHERE to this.state.player - it's properly used/set
2

You can use filter:

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

Comments

0

You don't need to use copy state to props, you can use this.props.players as well.

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

Then you can call let collection = getPlayers(); and map the players to html content.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.