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]);
CodePudding user response:
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.
CodePudding user response:
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".