pycan
pycan

Reputation: 351

State does not update when expected

I use filtering by category and text. Before every filtering by text I want to filter (reset) category, that is currently selected. When text changes, the category is not updated in this case. Do you have any idea why this happens? Thanks.

    handleSearchFilter = (searchText: string) => {
    const { selectedOption } = this.props;
    const { currentlyDisplayed } = this.state;

    this.handleSelectFilter(selectedOption);
    const newDisplayed = filter(currentlyDisplayed, (symbol: any) => symbol.name.cs.includes(searchText.toLowerCase()));
    this.setState({ currentlyDisplayed: newDisplayed });
};

handleSelectFilter = (selectedOption: string) => {
    const { symbols } = this.props;

    if (selectedOption === 'all') {
        this.setState({ currentlyDisplayed: symbols });
    } else {
        const newDisplayed = filter(symbols, (symbol: any) => symbol.category.includes(selectedOption.toLowerCase()));
        this.setState({ currentlyDisplayed: newDisplayed });
    }
};

Upvotes: 0

Views: 92

Answers (2)

Thiago Murakami
Thiago Murakami

Reputation: 995

I think you can achieve what you want by making a third function that returns newDislayed such as:

handleSearchFilter = (searchText: string) => {
    const { selectedOption } = this.props;
    const newDisplayed = this.getNewDisplayed(selectedOption, searchText);
    this.setState({ currentlyDisplayed: newDisplayed });
};

handleSelectFilter = (selectedOption: string) => {
    const newDisplayed = this.getNewDisplayed(selectedOption);
    this.setState({ currentlyDisplayed: newDisplayed });    
};

getNewDisplayed = (selectedOption: string, searchText = '') => {
    const { symbols } = this.props;
    if (selectedOption === 'all') {
        return symbols;
    } else {
        return filter(symbols, (symbol: any) => symbol.category.includes(selectedOption.toLowerCase()) && symbol.name.cs.includes(searchText.toLowerCase()) );
    }
}

Upvotes: 1

Yoan
Yoan

Reputation: 2207

I don't understand really well your filtering code but I'm pretty sure that your not expected behavior is because you are trying to modify the state 2 times in the handleSearchFilter method:

  1. this.handleSelectFilter(selectedOption); // That produce a change on currentlyDisplayed
  2. last line: this.setState({ currentlyDisplayed: newDisplayed });

I advise you to take a look of the reactjs doc (https://reactjs.org/docs/state-and-lifecycle.html) Basically, setStateis an Asynchronous method so you should not rely on their values for calculating the next state. What is happing its exactly that. Your first call ( this.handleSelectFilter(selectedOption); ) should be executing after the second one and overriding the result: currentlyDisplayed I hope that can help you. If you explain me better your idea of filtering and workflow I could help you with the code fix.

Upvotes: 0

Related Questions