React - filter object with useEffect

Viewed 39

I have an object about languages.

export const languageOptions = {
  en: {country: 'En', flag: require('../icons/ukflag.png')},
  ru: {country: 'Ru', flag: require('../icons/ruflag.png')},
  de: {country: 'De', flag: require('../icons/deflag.png')},
};

I want to filter when rendering components. I want to show droplist just en and de. I used useEffect, but it seems not working. After first click everything is working. No at the first rendering is not working.

const [selectedOption, setSelectedOption] = useState("Ru");
const [langListFiltered, setLangListFiltered] = useState();

useEffect(() => {
    setLangListFiltered(
      Object.fromEntries(
        Object.entries(languageOptions).filter(
          ([key]) => !key.includes(selectedOption)
        )
      )
    );
  }, [selectedOption]);

at the beginning

after click to change language

2 Answers

Either change your object of language to (here I changed keys of object):

export const languageOptions = {
  En: {country: 'En', flag: require('../icons/ukflag.png')},
  Ru: {country: 'Ru', flag: require('../icons/ruflag.png')},
  De: {country: 'De', flag: require('../icons/deflag.png')},
};

Or Change state initial value:

const [selectedOption, setSelectedOption] = useState("ru");
const [langListFiltered, setLangListFiltered] = useState();

useEffect(() => {
    setLangListFiltered(
      Object.fromEntries(
        Object.entries(languageOptions).filter(
          ([key]) => !key.includes(selectedOption)
        )
      )
    );
  }, [selectedOption]);

You need to go for any of the above solutions in order to solve your problem. I just changed values in the above solutions as they were not the same to do the comparison.

It is better to not store data in state which can be derived from state. Also, you don't need useEffect in this case, just do:

 const langListFiltered = React.useMemo(() => {
    return Object.fromEntries(
      Object.entries(languageOptions).filter(
        ([key]) => !key.includes(selectedOption)
      )
    );
  }, [selectedOption]);

PS. Reason why it didn't work in your case was your initial value of useState was "Ru" instead of "ru".

Related