admin管理员组

文章数量:1287776

I am trying to filter a list using react, but surprisingly, for such a mon task, cannot find anything online to help me achieve this.

I have an array of users which I then want to filter through (starting off with name - I can work out filtering by age then). The array is in my redux store and looks like the below.

let users = [
  {
    name: 'Raul',
    age: 29
  },
  {
    name: 'Mario',
    age: 22
  }
];

My entire ponent looks like the below.

class Test extends Component {

    constructor(props) {
        super(props);

        this.state = {
            users: this.props.users

        };

        this.filterList = this.filterList.bind(this);

    }

    ponentWillReceiveProps(nextProps) {

        this.setState({
            users: nextProps.users
        });

    }

    filterList(event) {

        let users = this.state.users;
        users = users.filter(function(user){
        //unsure what to do here
        });
        this.setState({users: users});
    }

  render(){

    const userList = this.state.users.map((user) => {
      return <li>{user.name} {user.age}</li>;
    });

    return(
      <input type="text" placeholder="Search" onChange={this.filterList}/>
      <ul>
        { userList }
      </ul>
    );

  }
}

I am trying to filter a list using react, but surprisingly, for such a mon task, cannot find anything online to help me achieve this.

I have an array of users which I then want to filter through (starting off with name - I can work out filtering by age then). The array is in my redux store and looks like the below.

let users = [
  {
    name: 'Raul',
    age: 29
  },
  {
    name: 'Mario',
    age: 22
  }
];

My entire ponent looks like the below.

class Test extends Component {

    constructor(props) {
        super(props);

        this.state = {
            users: this.props.users

        };

        this.filterList = this.filterList.bind(this);

    }

    ponentWillReceiveProps(nextProps) {

        this.setState({
            users: nextProps.users
        });

    }

    filterList(event) {

        let users = this.state.users;
        users = users.filter(function(user){
        //unsure what to do here
        });
        this.setState({users: users});
    }

  render(){

    const userList = this.state.users.map((user) => {
      return <li>{user.name} {user.age}</li>;
    });

    return(
      <input type="text" placeholder="Search" onChange={this.filterList}/>
      <ul>
        { userList }
      </ul>
    );

  }
}
Share Improve this question edited Mar 24, 2017 at 15:21 asked Mar 24, 2017 at 14:43 user7597670user7597670 2
  • what is the filter criteria? – pablogq Commented Mar 24, 2017 at 14:48
  • apologies @pablogq filter by name. well ideally both, but can start with name – user7597670 Commented Mar 24, 2017 at 14:49
Add a ment  | 

5 Answers 5

Reset to default 5

If you want to filter for name you can use .filter together with .startsWith or .indexOf to return true or false for a given user.

You've also set a new list of users on the onChange event, which results in an empty array sooner or later. Here I've used the user state that is only changed by the props, and a filteredUsers that is changed when a keystroke happened.

class Test extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      users: this.props.users,
      filteredUsers: this.props.users,
      q: ''
    };

    this.filterList = this.filterList.bind(this);
    this.onChange = this.onChange.bind(this);
  }

  ponentWillReceiveProps(nextProps) {
    this.setState(
      {
        users: nextProps.users,
        filteredUsers: nextProps.users
      },
      () => this.filterList()
    );
  }

  onChange(event) {
    const q = event.target.value.toLowerCase();
    this.setState({ q }, () => this.filterList());
  }

  filterList() {
    let users = this.state.users;
    let q = this.state.q;

    users = users.filter(function(user) {
      return user.name.toLowerCase().indexOf(q) != -1; // returns true or false
    });
    this.setState({ filteredUsers: users });
  }

  render() {
    const userList = this.state.filteredUsers.map(user => {
      return <li>{user.name} {user.age}</li>;
    });

    return (
      <div>
        <input
          type="text"
          placeholder="Search"
          value={this.state.q}
          onChange={this.onChange}
        />
        <ul>
          {userList}
        </ul>
      </div>
    );
  }
}

const userList = [
  {
    name: 'Raul',
    age: 29
  },
  {
    name: 'Mario',
    age: 22
  }
];

ReactDOM.render(<Test users={userList} />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

You need one more state variable to store the search result, initialise that variable by same data, once user type anything store the filtered data in that, Try this:

let users = [
  {
    name: 'Raul',
    age: 29
  },
  {
    name: 'Mario',
    age: 22
  }
];

class Test extends React.Component {

    constructor(props) {
        super(props);

        this.state = {
            users: users,
            result: users,
        };

        this.filterList = this.filterList.bind(this);

    }

    ponentWillReceiveProps(nextProps) {

        this.setState({
            users: nextProps.users,            
        });

    }

    filterList(event) {
        let value = event.target.value;
        let users = this.state.users, result=[];
        result = users.filter((user)=>{
            return user.name.toLowerCase().search(value) != -1;
        });
        this.setState({result});
    }

  render(){

    const userList = this.state.result.map((user) => {
      return <li>{user.name} {user.age}</li>;
    });

    return(<div>
      <input type="text" placeholder="Search" onChange={this.filterList}/>
      <ul>
        {userList}
      </ul>
      </div>
    );

  }
}

ReactDOM.render(<Test/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>


<div id='app'></div>

let datas =[
  {   
      "id":1,
      "title":"Ucat",
      "handle":"mi"
  },
  {
      "id":2,
      "title":"Acat",
      "handle":"csk"
  },
  {
      "id":3,
      "title":"Vcat",
      "handle":"kkr"
  },
  {
      "id":4,
      "title":"Atar",
      "handle":"pkbs"
  }];
const [search, setSearch] =useState(datas);
const handleInputChange = (e) => {
var dm = e.target.value;
var str =dm.toString();
var debug = datas.filter(x=> x["title"].toLowerCase().includes(str));
setSearch(debug);};


<input type="text"  onChange={handleInputChange}/>
{search.map((item)=>(
    <div key={item.id}>
        <ul>
            <li>
            {item.handle} 
            <br/>
            {item.title}
            </li>
        </ul>
    </div>
))};
  
  

If you want to filter the list, you must have a criteria to filter against. For instance you have a variable let filterAge = 18;

In that case you can filter the userlist against that value using

let users = users.filter(function(user){
    //return all users older or equal to filterAge
    return user.age >= filterAge;        
});

Every result from the function that equals true, will be added to the users variable. A false return will leave it out. How you determine true / false is up to you. Hardcode it (not very useful), a simple equals statement (as above) or a function doing higher math. Your choice.

It always worked well for me that way.

const [data, setData] = useState([{name: 'Kondo'}, {name: 'Gintoki'}])

const handleFilterFilesTable = () => {
    return data
      .filter((element) => {
        if (searchText !== "") {
          return element?.name?.toLowerCase()?.includes(searchText?.toLowerCase())
        }

        return element
      })
  }

// ...
return (
 //...
 <Table data={handleFilterFilesTable()} />
)

That way I can apply multiple filters working together simply by extending the filter method like this

// ...
return data.filter().filter().filter()//...
// ...

本文标签: ArraysJavascriptfilter array of objects using input searchStack Overflow