I have built a function component, DepartmentSelect, that uses react-select Async to allow users to select a department from a dropdown. I want to pass the id of the selected department in the props.
I have a working example, but it seems like I have duplicated logic. I passed a promise to the loadOptions react-select prop and I store the options in the state. I have the departmentId of the selected department in the DepartmentSelect props and I am storing the selected value in the state.
//... imports and getOptionLabel removed for brevity
const getOptionValue = (option) => {
return option.id;
};
interface Props {
departmentId: string,
onChange: (number) => void
}
let options = [];
const DepartmentSelect = (props: Props) => {
const [value, setValue] = useState(
options.find(o => o.id == props.departmentId)
);
const [isLoading, setLoading] = useState(true);
const handleChange = (option, action) => {
const id = option && option.id;
setValue(options.find(o => o.id == id));
props.onChange(id);
};
const loadOptions = () => {
return ky.get('/sbm/departments.json')
.then(r => r.json())
.then(json => {
options = json;
setValue(options.find(o => o.id == props.departmentId));
setLoading(false);
return json;
});
};
return (
<AsyncSelect
defaultOptions
getOptionValue={getOptionValue}
loadOptions={loadOptions}
onChange={handleChange}
value={value}
/>
);
};
export default DepartmentSelect;
The code is working. I have removed a few irrelevant lines to make it shorter. Is there a way I can have the same functionality without storing the options and value in the state?
This question is very similar to How can I work with just values in react-select onChange event and value prop?
In the above question, the options are passed in as a prop, so that they can get the selected prop without having to check if the options have been loaded from the server first. Would it be better to load the options separately and use a non-async select?
Edit
It would be nice if I could pass props.departmentId as the value prop to Async, but props.departmentId is a string. The value prop of Async requires one of the options, which are in the format
{
departmentId: string,
bill_cd: string,
name: string
}
props.onChange(id);sets the departmentId then why not set the value property of AsyncSelect to props.departmentId?