Search code examples
javascriptreactjscomponentsreact-props

I need to reset the state after filtering


I have a function in my parent component that takes the text of the selected item and filters through the response from an api but once it is filtered and displays the results I need it to reset back to no value for the text so a user can do multiple searches if needed. This is a part of my parent component that filters:

class Providers extends Component {
  state = {
    scope: "all",
    listItems: [],
  };

componentDidMount () {
   api.Providers.list({ scope: this.state.scope })
   .then(response => {
     this.setState({listItems: response.items})
    
   })
}
dropSearch = (e) => {
  
  let filteredList = this.state.listItems.slice().filter(i => i.fullName.includes(e) ||  i.active.includes(e) || i.capabilities.geographic && i.capabilities.geographic.includes(e))
  this.setState({listItems: filteredList})
}
render() {
    const isManager =
      this.props.currentUser &&
      this.props.currentUser.permissions.indexOf("manage") !== -1;
    const isDirector =
      this.props.currentUser &&
      this.props.currentUser.permissions.indexOf("medicalDirector") !== -1;
    return (
 <RemoteList
              listItems={this.state.listItems}
              listName="providers"
            >
              <List onProviderStateChange={this.providerStateChanged} dropSearch={this.dropSearch}/>
            </RemoteList>
);
  }

and here is where i get the value i am passing to my parent in the child component through the dropSearch prop:

const List = ({
  items,
  permissions,
  currentUser,
  onProviderStateChange,
  dropSearch,
  ...props
}) => {
  
  const providers = items || [];
  const hasAudit = permissions.indexOf("medicalDirector") !== -1;
  const hasEdit = permissions.indexOf("manage") !== -1;


  return (
    <Table className="provider-list">
      <thead>
        <Row className="provider-header">
          <Col md={hasAudit ? "2" : "3"}>
            <UncontrolledDropdown>
              <DropdownToggle tag="a" caret>
                Provider
              </DropdownToggle>
              <DropdownMenu style={{ maxHeight:"400px", overflow: "scroll"}}>
                {providers.map((name) => (
                  <DropdownItem tag="a" onClick={(e) => dropSearch(e.target.text)} style={{ color: "rgb(68, 68, 68)", fontSize: "12px" }}>{name.fullName}</DropdownItem>
                ))}
              </DropdownMenu>
            </UncontrolledDropdown>
          </Col>
          <Col md={hasAudit ? "2" : "3"}>
            <UncontrolledDropdown>
              <DropdownToggle tag="a" caret>
                Location
              </DropdownToggle>
              <DropdownMenu style={{ maxHeight:"400px", overflow: "scroll"}}>
                {stateChoices.map((states) => (
                  <DropdownItem tag="a" onClick={(e) => dropSearch(e.target.text)} style={{ color: "rgb(68, 68, 68)", fontSize: "12px" }}>{states}</DropdownItem>
                ))}
              </DropdownMenu>
            </UncontrolledDropdown>
          </Col>

How could i have the e.target.value reset to nothing after rendering so that the user can search again?


Solution

  • You don't need to mutate your list, keep it allways in full version. Then on dropSearch just save search text to state, and then filter by it, like this:

    dropSearch = (searchValue) => {
     this.setState({searchValue})
    }
    

    Then in your List put full list and filter it on fly. You can use some helper function

    filterListItemsHelper () => {
      const {searchValue} = this.state;
      return this.state.listItems.slice().filter(i => i.fullName.includes(searchValue) ... || [];
    }
    
    <RemoteList
        listItems={this.filterListItemsHelper()}
        listName="providers"
     >