1

I am displaying components on base of state which is an array. When I am trying to sort this state it doesn't rerender components rendered on base of it. I want to sort on base of sortBy state so when its being changed (using select) I invoke sorting function using useEffect(). What am I doing wrong?

const sortCountries = () => {
    switch (sortBy) {
      case sortBySwitchList.Alphabetically:
        setCountriesArr((prev) =>
          prev.sort((a, b) =>
            a.name.common < b.name.common
              ? -1
              : a.name.common > b.name.common
              ? 1
              : 0
          )
        );
        break;
      case sortBySwitchList.AlphabeticallyReversed:
        setCountriesArr((prev) =>
          prev.sort((a, b) =>
            a.name.common < b.name.common
              ? 1
              : a.name.common > b.name.common
              ? -1
              : 0
          )
        );
        break;
      default:
        return;
    }
  };
  const changeSortBy = (e) => {
    setSortBy(e.target.value);
  };

  useEffect(() => {
    sortCountries();
  }, [sortBy]);
***part in which I am rendering***
{countriesArr.map((item) => {
          return (
            <CountryComponent
              key={item.name.common}
              flag={item.flags.png}
              name={item.name.common}
              population={item.population}
              region={item.region}
              capital={item.capital}
            />
          );
        })}

1 Answer 1

3

Sort does sorting an Array in place (mutates the original array) so instead make a copy of it and then sort like so ..

same for the other sort you are doing :)

setCountriesArr((prev) =>
      [...prev].sort((a, b) =>
        a.name.common < b.name.common
          ? -1
          : a.name.common > b.name.common
          ? 1
          : 0
      )
    );
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.