1

I have a React Table(https://react-table.js.org) which gets populated from the data coming from an API. Above the table I have created a filter component which consists of a dropdown with multiple options. Once specific parameters are selected from the dropdown, I need to filter the Table based on the selected parameters. I store the state of the filter component and the state of the table component separately. Since both the table and the filter are separate components , how to take the values from the filter component and filter the table? My Table is as follows:

<ReactTable
data={tableData}
noDataText="No Appointments"
loading={this.props.loading}
showPagination={false}
filterable
defaultFilterMethod={(filter, row) =>
  String(row[filter.id]) === filter.value}
columns={[
  {
    columns: [
      {
        sortable: false,
        filterable: false,
        Header: "Id",
        accessor: "resourceId",
        headerStyle: {
          background: '#ECEFF1',
        },
      },
      {
        sortable: false,
        filterable: false,
        Header: "Tenant Name",
        accessor: "Name",
        id: "Tenant Name",
        headerStyle: {
          background: '#ECEFF1',
        },
      },
 </ReactTable>

My filter component is as follows:

export default class PopoverExampleAnimation extends 
React.Component {

constructor(props) {
super(props);

this.state = {
  open: false,
  clicked: [],
  Id: '',
  tenantName: '',
};

this.handleRequestClose = this.handleRequestClose.bind(this);
this.getId = this.getId.bind(this);
this.getTenantName = this.getTenantName.bind(this);

}

handleTouchTap = (event) => {
// This prevents ghost click.
 event.preventDefault();

this.setState({
  open: true,
  anchorEl: event.currentTarget,
  });
 };

handleRequestClose = () => {
  this.setState({
  open: false,
  });
 };

getId = (Id) => {
    console.log(Id);
    this.setState({Id});
}

getTenantName = (tenantName) => {
 console.log(tenantName);
this.setState({tenantName});
}

render() {
return (
  <div>
    <RaisedButton
        onClick={this.handleTouchTap}
        label="FILTER"
        labelColor="#26A69A"
    />
    <Popover
        open={this.state.open}
        anchorEl={this.state.anchorEl}
        anchorOrigin={{ horizontal: 'left', vertical: 'bottom' }}
        targetOrigin={{ horizontal: 'left', vertical: 'top' }}
        onRequestClose={this.handleRequestClose}
        animation={PopoverAnimationVertical}
    >
      <Menu>
        <MenuItem
            primaryText={"NAME - " + this.state.tenantName}
            rightIcon={<ArrowDropRight />}
            menuItems={[
              <MenuItem 
              primaryText="Group 1" 
              onClick={() =>
                this.getTenantName('Group 1')
              }
              />,
              <Divider />,
              <MenuItem primaryText="Group 2"
              onClick={() =>
                this.getTenantName('Group 2')
              }
              />,
            ]}
        />

        <Divider />
        <MenuItem
            primaryText={"ID -   " + this.state.Id}
            rightIcon={<ArrowDropRight />}
            menuItemStyle={{ backgroundcolor: '#E0F2F1' }}
            menuItems={[
              <MenuItem primaryText="1" onClick={() =>
                this.getId('1')
              }
              />,
              <Divider />,
              <MenuItem primaryText="2" onClick={() =>
                this.getId('2')
              }
              />,
              <Divider />,
              <MenuItem primaryText="3" onClick={() =>
                this.getId('3')
              }
              />,
              <Divider />,
              <MenuItem primaryText="4" onClick={() =>
                this.getId('4')
              }
              />,
            ]}
        />
        <Divider />
        <RaisedButton
            label="APPLY"
            style={{ margin: 2, width: '60px' }}
            labelColor="#FAFAFA"
            backgroundColor="#26A69A"
        />
        <RaisedButton
            label="CANCEL"
            style={{ margin: 22, width: '60px' }}
            labelColor="#26A69A"
            onClick={() =>
              //this.getId(' ')
              this.handleRequestClose()
             }
        />

      </Menu>
    </Popover>
  </div>
  );
 }
}

Both the table and filter are separate components and Im not using Redux for state management.

2
  • "Im not using Redux for state management": Why not? It is the most obvious solution to your problem. Commented Oct 5, 2017 at 13:59
  • 1
    @JulienD not necessarily. Redux is great, but not necessarily needed by all. If it is the only case he/she needs communication between components lifting the state up is also a valid option. Commented Oct 5, 2017 at 14:02

1 Answer 1

1

My understanding of your setup, you have:

<FilterComponent /> <!-- Stores instructions for Filters to apply -->
<TableComponent /> <!-- Displays data -->

And you expect that when the user makes changes in the filter component, the table component MUST reflect the changes.

If the above is true, the recommended way to do so (without relying on state management libraries) is lifting the state to the least common ancestor (see official docs).

If you do not have a least common ancestor, do not hesitate introducing a container component instead.

This component should serve the following function:

  • It knows/stores the state of the FilterComponent or is able to consume the filter instructions from the FilterComponent
  • It holds the data & filteredData in its state. filteredData can be passed to the table component as Props
  • Every time it gets a signal from FilterComponent to "apply" a filter, it should filter the data (leading to change of filteredData in its state, which should make the table component re-render)

i.e. in your FilterComponent, when you click the Apply button, the internal state is lifted to the "container" component and that leads to recomputation of the data to be displayed in your TableComponent. The table should re-render itself when the data changes.

I hope it opens your mind to the possibilities and you can then best decide which component holds what state and what responsibilities.

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

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.