I have a input delay issue when I try to set the state of a zustand variable in onChange event.
const BuildOrder = (props: { setOpen: Function }) => {
const { almacenes, isLoadingAlmacenes } = useGetAlmacenes();
const { articlesRes, isLoadingArticles } = useGetArticlesBySearch();
const {
warehouseSelected,
setWarehouseSelected,
setArticles,
articles,
setArticlesFetched,
articlesFetched,
setSearch,
} = useDirectlyPurchaseRequestOrderStore(
(state) => ({
warehouseSelected: state.warehouseSelected,
setWarehouseSelected: state.setWarehouseSelected,
setArticles: state.setArticles,
articles: state.articles,
setArticlesFetched: state.setArticlesFetched,
articlesFetched: state.articlesFetched,
setSearch: state.setSearch,
}),
shallow
);
const [articleSelected, setArticleSelected] = useState<Article | null>(null);
const [amountText, setAmountText] = useState('');
const [warehouseError, setWarehouseError] = useState(false);
const [articleError, setArticleError] = useState(false);`your text`
const [amountError, setAmountError] = useState(false);
if (isLoadingAlmacenes)
return (
<Box sx={{ display: 'flex', flex: 1, justifyContent: 'center', p: 6 }}>
<CircularProgress size={40} />
</Box>
);
return (
<Stack sx={{ display: 'flex', flex: 1, mt: 2 }}>
<Stack sx={{ display: 'flex', flex: 1, maxWidth: 300 }}>
<Typography sx={{ fontWeight: 500, fontSize: 14 }}>Seleccionar almacén</Typography>
<TextField
select
label="Almacén"
size="small"
error={warehouseError}
helperText={warehouseError && 'Selecciona un almacén'}
value={warehouseSelected}
onChange={(e) => {
setWarehouseError(false);
setWarehouseSelected(e.target.value);
}}
>
{almacenes.map((warehouse) => (
<MenuItem key={warehouse.id} value={warehouse.id}>
{warehouse.nombre}
</MenuItem>
))}
</TextField>
</Stack>
<Divider sx={{ my: 2 }} />
<Box
sx={{
display: 'flex',
flex: 1,
justifyContent: 'space-between',
columnGap: 2,
flexDirection: { xs: 'column', sm: 'row' },
rowGap: { xs: 2, sm: 0 },
}}
>
<Stack sx={{ display: 'flex', flex: 1 }}>
<Typography sx={{ fontWeight: 500, fontSize: 14 }}>Seleccionar articulo</Typography>
<Autocomplete
disablePortal
fullWidth
filterOptions={filterArticleOptions}
onChange={(e, val) => {
e.stopPropagation();
setArticleSelected(val);
setArticleError(false);
}}
loading={isLoadingArticles && articlesFetched.length === 0}
getOptionLabel={(option) => option.nombre}
options={articlesFetched}
value={articleSelected}
noOptionsText="No se encontraron artículos"
renderInput={(params) => (
<TextField
{...params}
error={articleError}
helperText={articleError && 'Selecciona un articulo'}
placeholder="Artículos"
sx={{ width: '50%' }}
onChange={(e) => {
setSearch(e.target.value);
}}
/>
)}
/>
</Stack>
In this Autocomplete I render dynamically my articles, I render an input TextField to controll the search state to render a few items, when I write in my TextField thats update my value store in onChange event but thats create a input delay on the textField and looks so laggy.
export const useGetArticlesBySearch = () => {
const [isLoadingArticles, setIsLoadingArticles] = useState(true);
const [articlesRes, setArticles] = useState<Article[]>([]);
const search = useDirectlyPurchaseRequestOrderStore(useShallow((state) => state.search));
useEffect(() => {
const fetchData = async () => {
setIsLoadingArticles(true);
try {
const res = await getArticlesBySearch(search);
setArticles(res);
} catch (error) {
console.log(error);
} finally {
setIsLoadingArticles(false);
}
};
fetchData();
}, [search]);
return { isLoadingArticles, articlesRes };
};
I call the state value of my store here an search the articles.
I solved the issue creating a useState and prop to my custom hook but I want to know, is there another way to do only with zustand?
I tried to know is there a way to state a zustand store variable and avoid input delay on textfield.
I have seen some examples where instead of destructing all the state in the same line, they would separate each item per line:
const warehouseSelected = useDirectlyPurchaseRequestOrderStore((state) => state.warehouseSelected)
const setWarehouseSelected = useDirectlyPurchaseRequestOrderStore((state) => state.setWarehouseSelected)
...rest of the items
I would try this to see if it improves performance