-1

Guys I am new to React and I am having problems to update the State twice in a single call.
I am trying to filter the visible rows on a React Table based on their Gender.

Below is my State with data that is filtered and updated and a backup defaultData to reset the data.

this.state = {


  data: [      

    {'id':1,first_name:'Ilka',last_name:'Riddel',email:'iriddel0@blogger.com',gender:'Female'},
    {'id':2,first_name:'Myrwyn',last_name:'Skinner',email:'mskinner1@cmu.edu',gender:'Male'},
    {'id':3,first_name:'Almira',last_name:'Kubu',email:'akubu2@google.ru',gender:'Female'},
    {'id':4,first_name:'Eloisa',last_name:'Maltster',email:'emaltster3@phoca.cz',gender:'Female'},
    {'id':5,first_name:'Vite',last_name:'Capin',email:'vcapin4@noaa.gov',gender:'Male'},
    {'id':6,first_name:'Zelig',last_name:'Crippin',email:'zcrippin5@blogtalkradio.com',gender:'Male'},
    {'id':7,first_name:'Persis',last_name:'Middlemiss',email:'pmiddlemiss6@discovery.com',gender:'Female'},
    {'id':8,first_name:'Amelina',last_name:'Biddy',email:'abiddy7@noaa.gov',gender:'Female'},
    {'id':9,first_name:'Darrell',last_name:'Kemme',email:'dkemme8@clickbank.net',gender:'Male'},
    {'id':10,first_name:'Kerianne',last_name:'Formby',email:'kformby9@berkeley.edu',gender:'Female'}
  ],
  defaultData: [      

    {'id':1,first_name:'Ilka',last_name:'Riddel',email:'iriddel0@blogger.com',gender:'Female'},
    {'id':2,first_name:'Myrwyn',last_name:'Skinner',email:'mskinner1@cmu.edu',gender:'Male'},
    {'id':3,first_name:'Almira',last_name:'Kubu',email:'akubu2@google.ru',gender:'Female'},
    {'id':4,first_name:'Eloisa',last_name:'Maltster',email:'emaltster3@phoca.cz',gender:'Female'},
    {'id':5,first_name:'Vite',last_name:'Capin',email:'vcapin4@noaa.gov',gender:'Male'},
    {'id':6,first_name:'Zelig',last_name:'Crippin',email:'zcrippin5@blogtalkradio.com',gender:'Male'},
    {'id':7,first_name:'Persis',last_name:'Middlemiss',email:'pmiddlemiss6@discovery.com',gender:'Female'},
    {'id':8,first_name:'Amelina',last_name:'Biddy',email:'abiddy7@noaa.gov',gender:'Female'},
    {'id':9,first_name:'Darrell',last_name:'Kemme',email:'dkemme8@clickbank.net',gender:'Male'},
    {'id':10,first_name:'Kerianne',last_name:'Formby',email:'kformby9@berkeley.edu',gender:'Female'}
  ]
};

I have handler methods to filter the data and update the state.

If they click the "Show All Men" then the handleShowOnlyMale fuction will filter the data in the state and remove all females in the data and when they click the showAllFemale the table will then be empty because all females were already removed. I do not want this behavior and want a toggle like effect between male and female records in the table.

    handleResetData(){
    //console.log(this.state.data);
    this.setState({
        data: this.state.defaultData        
    })
  }

  handleShowOnlyMale(){
    //handleResetData();
    // this.setState((prevState) => {
    //     return {data: prevState.defaultData};
    //   }),
    this.setState({        
        data: this.state.data.filter(person => person.gender === 'Male')
    })    
  }

  handleShowOnlyFemale(){
    //handleResetData();
    // this.setState((prevState) => {
    //     return {data: prevState.defaultData};
    //   }),
    this.setState({        
        data: this.state.data.filter(person => person.gender === 'Female')
    })  
  }

My work around is to update data : this.state.defaultData everytime, before they start filtering.
How do I do this properly?

BELOW IS MY COMPLETE CODE:

import React from "react";
import { render } from "react-dom";


// Import React Table
import ReactTable from "react-table";
import "react-table/react-table.css";

class App extends React.Component {
  constructor() {
    super();
    this.state = {


      data: [      

        {'id':1,first_name:'Ilka',last_name:'Riddel',email:'iriddel0@blogger.com',gender:'Female'},
        {'id':2,first_name:'Myrwyn',last_name:'Skinner',email:'mskinner1@cmu.edu',gender:'Male'},
        {'id':3,first_name:'Almira',last_name:'Kubu',email:'akubu2@google.ru',gender:'Female'},
        {'id':4,first_name:'Eloisa',last_name:'Maltster',email:'emaltster3@phoca.cz',gender:'Female'},
        {'id':5,first_name:'Vite',last_name:'Capin',email:'vcapin4@noaa.gov',gender:'Male'},
        {'id':6,first_name:'Zelig',last_name:'Crippin',email:'zcrippin5@blogtalkradio.com',gender:'Male'},
        {'id':7,first_name:'Persis',last_name:'Middlemiss',email:'pmiddlemiss6@discovery.com',gender:'Female'},
        {'id':8,first_name:'Amelina',last_name:'Biddy',email:'abiddy7@noaa.gov',gender:'Female'},
        {'id':9,first_name:'Darrell',last_name:'Kemme',email:'dkemme8@clickbank.net',gender:'Male'},
        {'id':10,first_name:'Kerianne',last_name:'Formby',email:'kformby9@berkeley.edu',gender:'Female'}
      ],
      defaultData: [      

        {'id':1,first_name:'Ilka',last_name:'Riddel',email:'iriddel0@blogger.com',gender:'Female'},
        {'id':2,first_name:'Myrwyn',last_name:'Skinner',email:'mskinner1@cmu.edu',gender:'Male'},
        {'id':3,first_name:'Almira',last_name:'Kubu',email:'akubu2@google.ru',gender:'Female'},
        {'id':4,first_name:'Eloisa',last_name:'Maltster',email:'emaltster3@phoca.cz',gender:'Female'},
        {'id':5,first_name:'Vite',last_name:'Capin',email:'vcapin4@noaa.gov',gender:'Male'},
        {'id':6,first_name:'Zelig',last_name:'Crippin',email:'zcrippin5@blogtalkradio.com',gender:'Male'},
        {'id':7,first_name:'Persis',last_name:'Middlemiss',email:'pmiddlemiss6@discovery.com',gender:'Female'},
        {'id':8,first_name:'Amelina',last_name:'Biddy',email:'abiddy7@noaa.gov',gender:'Female'},
        {'id':9,first_name:'Darrell',last_name:'Kemme',email:'dkemme8@clickbank.net',gender:'Male'},
        {'id':10,first_name:'Kerianne',last_name:'Formby',email:'kformby9@berkeley.edu',gender:'Female'}
      ],


      firstNameSelected: true,
      showMale: true,
      showFemale: true
    };

  }
  handleInputChange(value) {
      console.log(this.state.data);
    this.setState({ firstNameSelected: !this.state.firstNameSelected });
  }

  handleToUpperCaseFirstName(){    
    // this.setState({
    //         data: this.state.data.map(a => a.toUpperCase())
    //     }) 
  }

  handleResetData(){
    //console.log(this.state.data);
    this.setState({
        data: this.state.defaultData        
    })
  }

  handleShowOnlyMale(){
    //handleResetData();
    // this.setState((prevState) => {
    //     return {data: prevState.defaultData};
    //   }),
    this.setState({        
        data: this.state.data.filter(person => person.gender === 'Male')
    })    
  }

  handleShowOnlyFemale(){
    //handleResetData();
    // this.setState((prevState) => {
    //     return {data: prevState.defaultData};
    //   }),
    this.setState({        
        data: this.state.data.filter(person => person.gender === 'Female')
    })  
  }

  render() {
    const { data, firstNameSelected } = this.state;
    return (
      <div>
        <div>

          <button 
            onClick={this.handleToUpperCaseFirstName}>
            HIGHLIGHT FIRSTNAME (UPPERCASE)
          </button>

          <button 

            onClick={this.handleShowOnlyMale.bind(this)}>Show All Men</button>
          <button 

            onClick={this.handleShowOnlyFemale.bind(this)}>Show All The Ladies</button>
        </div>


        <ReactTable
          data={data}
          columns={[
            {

              columns: [
                {
                  Header: "First Name",
                  accessor: "first_name",
                  show: firstNameSelected
                },
                {
                  Header: "Last Name",
                  id: "last_name",
                  //show: firstNameSelected,
                  accessor: d => d.last_name
                }
              ]
            },
            {

              columns: [
                {
                  Header: "Email",
                  accessor: "email"
                },
                {
                  Header: "Gender",
                  accessor: "gender"
                }
              ]
            },

          ]}
          defaultPageSize={10}
          className="-striped -highlight"
        />
        <br />

      </div>
    );
  }
}

render(<App />, document.getElementById("root"));
TwoThumbSticks
  • 1,086
  • 3
  • 23
  • 38
  • Search for any react TODO project / tutorial - filtering is the basic feature and usually done far better/simpler/more universal... – xadm Apr 09 '19 at 10:50

2 Answers2

1

You can keep your data in state and return only filtered values like this:

 handleShowOnlyMale() {
   return this.state.data.filter(person => person.gender === 'Male');
 }

 handleShowOnlyFemale(){
   return this.state.data.filter(person => person.gender === 'Female');  
 }
Igor Staszewski
  • 401
  • 2
  • 8
  • 1
    The react table does not automatically reflect the filtered data from state.data Is it because react only renders / re-renders the component when there is changes in the State, and since we just returned the this.state.data.filer the State wont automatically update the React Table – TwoThumbSticks Apr 09 '19 at 14:53
0

Why do You not use defaultData to filter

handleShowOnlyMale(){
   this.setState({        
    data: this.state.defaultData.filter(person => person.gender === 'Male')
   })    
 }

handleShowOnlyFemale(){
   this.setState({        
    data: this.state.defaultData.filter(person => person.gender === 'Female')
  })  
 }
Ryan Nghiem
  • 2,417
  • 2
  • 18
  • 28