简体   繁体   中英

How to filter values for multiple data using reactjs?

I'm new to react and want to make search filter for multiple data in the object. I've tried for filtering single data, code is as shown below:

    var {Data, search} =this.state;
            search = this.state.search.trim().toLowerCase();
        if (search.length > 0) {
          Data= Data.filter(function(i) {
            return i.firstName.toLowerCase().match( search );

          });
        }

It is working great but only for the firstName. But my objective is to get filter for lastName, Location and Skills also.

Here is the code:

export default class DataView extends React.Component {
  constructor() {
    super();
    this.state = {
      Data: [],
      search: ""
    };
  }
  componentDidMount() {
    this.fetchData();
  }
  fetchData() {
    fetch("api/Profile")
      .then(response => response.json())
      .then(data => {
        this.setState({
          Data: data.item1
        });
      });
  }
  handleSearch = e => {
    this.setState({ search: e.target.value });
  };

  render() {
    var { Data, search } = this.state;
    search = this.state.search.trim().toLowerCase();
    if (search.length > 0) {
      Data = Data.filter(function(i) {
        return i.firstName.toLowerCase().match(search);
      });
    }

    return (
      <div>
        <Segment className="p_segment">
          <Input
            icon="search"
            placeholder="Search..."
            className="a_Search"
            value={this.state.search}
            onChange={this.handleSearch}
          />
        </Segment>

        <Container className="p_view">
          {Data.map(View => {
            return (
              <Grid key={View.id}>
                <Grid.Row className=" p_header">
                  <Checkbox className="p_checkbox" />
                  <Header>
                    {" "}
                    {View.firstName} {View.lastName}{" "}
                  </Header>
                </Grid.Row>
                <Divider className="p_divider" />
                <Grid.Row>
                  <Icon name="marker" /> {View.location}
                  <Divider className="p_divider" />
                </Grid.Row>
                <Grid.Row>
                  <Grid.Column>
                    <div>
                      <div className="g_column">
                        {View.skillset.map(data => {
                          return (
                            <Label className="c_label">{data.skill}</Label>
                          );
                        })}
                      </div>
                    </div>
                  </Grid.Column>
                </Grid.Row>
              </Grid>
            );
          })}
        </Container>
      </div>
    );
  }
}

Can anyone help me in this Query?

You can simply make an OR statement

return i.firstName.toLowerCase().match( search ) || i.skills.toLowerCase().match( search ) || i.location.toLowerCase().match( search );

Or if you want to search the full object

return JSON.stringify(i).toLowerCase().match(search);

If case-insensitive partial match across the object values is what you've been after, you may simply extract Object.values() into an array and make use of Array.prototype.some() together with Array.prototype.filter() in a similar way to what you did:

 const stateData = [{ firstName: 'Stephen', lastName: 'Smith', location: 'Johannesburg', //match by location skills: 'golf' },{ firstName: 'George', lastName: 'Washington', location: 'Philadelphia', skills: 'majohng' //match by skills },{ firstName: 'Dummy', lastName: 'Dummyson', location: 'Dummywille', skills: 'dummy' }], searchString = 'jo', searchResult = stateData.filter(record => Object .values(record) .some(prop => prop .toLowerCase() .includes(searchString.toLowerCase()) ) ) console.log(searchResult)
 .as-console-wrapper{min-height:100%;}

Some notation.

var { Data, search } = this.state; // don't use var
    search = this.state.search.trim().toLowerCase(); // don't do mutation
    if (search.length > 0) {
      Data = Data.filter(function(i) { // don't do mutation
        return i.firstName.toLowerCase().match(search);
      });
    }
  1. Add result to state.
  2. use componentDidUpdate .
  3. check if the search filed was changed.
  4. do filter.
  5. reset result if the search field empty.

 import React from "react"; export default class DataView extends React.Component { constructor(props) { super(props); this.state = { data: [], search: "", result: [], // [1] }; } componentDidMount() { this.fetchData(); } componentDidUpdate(prevProps, prevState) { // [2] const { search: prevSearch } = prevState; const { search: nextSearch, data } = this.state; if (prevSearch !== nextSearch) { // [3] const trimed = nextSearch.trim().toLowerCase(); const result = nextSearch.length > 0 ? data.filter(({ firstName, lastName }) => ( // [4] `${firstName} ${lastName}`.toLowerCase().includes(trimed) )) : []; // [5] this.setState({ result }); } } fetchData() { fetch("api/Profile") .then(response => response.json()) .then(({ item1 }) => { this.setState({ data: item1 }); }); } handleSearch = (e) => { this.setState({ search: e.target.value }); }; render() { const { data, search, result } = this.state; return ( <div> <Segment className="p_segment"> <Input icon="search" placeholder="Search..." className="a_Search" value={search} onChange={this.handleSearch} /> </Segment> <Container className="p_view"> {result.map((view) => { const { id, firstName, lastName, location, skillset, } = view; return ( <Grid key={id}> <Grid.Row className=" p_header"> <Checkbox className="p_checkbox" /> <Header> {` ${firstName} ${lastName} `} </Header> </Grid.Row> <Divider className="p_divider" /> <Grid.Row> <Icon name="marker" /> {location} <Divider className="p_divider" /> </Grid.Row> <Grid.Row> <Grid.Column> <div> <div className="g_column"> {skillset.map(({ skill }) => ( <Label className="c_label">{skill}</Label> ))} </div> </div> </Grid.Column> </Grid.Row> </Grid> ); })} </Container> </div> ); } }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM