¿Cómo puedo asegurarme de que la llamada al backend solo se realiza después de que se ejecute setState?
En el proyecto en el que estoy trabajando actualmente hay varios de estos:
“`
const SelectOptions = ({
defaultValue,
label,
name,
options,
onChangeFilter,
multiple,
onCloseFilter
}) => {
const [option, setOption] = useState(defaultValue);
useEffect(() => {
setOption(defaultValue);
}, [defaultValue]);
const onChangeOption = event => {
const { value } = event.target;
setOption(value);
onChangeFilter(name, value);
};
return (
<FormControl size="small" variant="outlined" fullWidth>
<InputLabel>{label}</InputLabel>
<Select
label={label}
value={option}
onChange={onChangeOption}
multiple={multiple}
renderValue={selected => (multiple ? selected.join(', ') : selected)}
MenuProps={{
getContentAnchorEl: null
}}
onClose={() => onCloseFilter() }
>
{!multiple && <MenuItem value="">Select</MenuItem>}
{options.map(item => (
<MenuItem key={item} value={item}>
{multiple && <Checkbox checked={option.includes(item)} />}
<ListItemText primary={item} />
</MenuItem>
))}
</Select>
</FormControl>
);
};
Estas llaman a las siguientes dos funciones en el componente padre:
const onChangeFilter = (name, value) => {
setFilters(prevState => ({ …prevState, [name]: value }));
};
const onCloseFilter = () => {
fetchData();
};
Quiero establecer todos los filtros y solo cuando cierre el <Select />
debe realizarse la llamada al backend para aplicar los filtros. Esto se hace a través de esta función:
const fetchData = () => {
const payload = { data: { id: record.id }, filter: { ...filters } };
mutate(
{ type: 'fetchData', resource: 'data', payload },
{
onSuccess: (response) => {
setData(response.data);
},
onFailure: () => {
notify('ra.notification.http_error');
}
}
)
};
El problema es que fetchData()
se ejecuta antes de que setFilters(...)
termine. No puedo ejecutar fetchData()
dentro de onChangeFilter
porque resultaría en demasiadas solicitudes.
¿Cómo me aseguro de que fetchData()
se ejecute solo después de cerrar el <Select />
y después de que setFilters(...)
actualice todos mis filtros con las opciones que elegí?
davy.ai
Para asegurarte de que
fetchData()
solo se ejecute después de cerrar el<select></select>
y después de quesetFilters(...)
haya actualizado todos tus filtros con las opciones que elegiste, puedes almacenar las opciones seleccionadas en una variable de estado en el componente padre y pasarla al componenteSelectOptions
como una propiedad.Luego, en el componente
SelectOptions
, puedes actualizar la variable de estado en el componente padre a través de la funciónonChangeFilter
, lo que provocará una nueva representación del componente padre con los filtros actualizados.Finalmente, en el componente padre, puedes agregar una variable de estado para mantener un seguimiento de cuándo se cierra el
<select></select>
, y solo llamar afetchData()
cuando esta variable de estado es verdadera. Puedes actualizar esta variable de estado pasando una función de devolución de llamada a la propiedadonCloseFilter
del componenteSelectOptions
.Aquí tienes un ejemplo de implementación:
En este ejemplo,
selectedOptions
es la variable de estado que contiene las opciones seleccionadas, y se actualiza cada vez que se selecciona una opción en el<select></select>
.onChangeFilter
actualiza tantoselectedOptions
comofilters
con el valor y el nombre seleccionados.onCloseFilter
establece la variable de estado deisSelectClosed
en verdadero, lo que provoca una nueva representación del componente padre, y cuando se cierra el<select></select>
, se llama afetchData()
, que actualiza los datos en función de los últimos filtros. Finalmente,isSelectClosed
se restaura a falso.