I have the following array:
export const VALID_LANGUAGES = [
{ label: "English", value: "en" },
{ label: "French", value: "fr" },
{ label: "Italian", value: "it" },
{ label: "Portuguese", value: "pt" },
{ label: "Spanish", value: "sp" },
];
And I want to make sure that a component receive, as a prop "language", one of these values. How can I do it?
MyComponent.propTypes = {
language: PropTypes.oneOf(VALID_LANGUAGES).isRequired, // Doesn't work :(
};
I think you just need to map the array to a list of valid language entries. The label
property seems like the value you want.
language: PropTypes.oneOf(VALID_LANGUAGES.map(({ label }) => label).isRequired
If you instead want the language code just map the value.
language: PropTypes.oneOf(VALID_LANGUAGES.map(({ value }) => value).isRequired
Actually, I just tested your original code and it also works. Each value is validated until the last option "Klingon" which is invalid and a proptypes error is logged. Here's a codesandbox demo:
const VALID_LANGUAGES = [
{ label: "English", value: "en" },
{ label: "French", value: "fr" },
{ label: "Italian", value: "it" },
{ label: "Portuguese", value: "pt" },
{ label: "Spanish", value: "sp" }
];
const MyComponent = ({ language }) => <div>Language: {language.label}</div>;
MyComponent.propTypes = {
language: PropTypes.oneOf(VALID_LANGUAGES).isRequired
};
export default function App() {
const [language, setLanguage] = React.useState(0);
return (
<div className="App">
<select onChange={(e) => setLanguage(e.target.value)} value={language}>
<option value={-1} disabled>
Select a Language
</option>
{VALID_LANGUAGES.map((language, index) => (
<option key={language.value} value={index}>
{language.label}
</option>
))}
<option value={-1}>Klingon</option>
</select>
<MyComponent language={VALID_LANGUAGES[language]} />
</div>
);
}
Perhaps you can clarify what and/or how your code isn't working.