Estou fazendo um projeto em React que preciso preencher um formulário e então enviar o que foi respondido para meu BD, para fazer isso eu queria usar o hook useDebounce para enviar o envio depois que o usuário parasse a interação. Mas quando eu tentei fazer isso, resultou em um loop infinito e eu não sei como implementar isso.
Esta é minha revisão de código:
Primeiro, tenho meu gancho que contém todas as operações dessa entidade usando GraphQL:
// useRecommendation.js
...
// other operations
export const useUpdate = () => {
const [updateCriteria, { loading, error }] = useMutation(UPDATE_CRITERIA);
const update = { handle: updateCriteria, loading, error };
return update;
};
Então importo todas as operações para um objeto como um modelo:
// Recommendation.js
const Recommendation = {
all: useGetAll,
byCategory: useGetByCategory,
create: useCreate,
update: useUpdate
}
export default Recommendation
E então estou importando esta entidade no meu manipulador de componentes:
export const useRecommendationFormHandler = ({ form }) => {
const updateRecommendation = Criteria.update();
const submitRecommendation = async () => {
try {
const { data } = await updateRecommendation.handle({
variables: {
input: {
conformity: form.conformity,
importance: form.importance,
comment: form.comment,
conclusion: form.conformity === 0 && form.importance !== null,
},
criteria_id: form.id
}
});
return data;
} catch (error) {
console.error("Erro ao atualizar a criteria", error);
}
};
return {
isLoading: updateRecommendation.loading
}
};
Acho importante dizer que o componente que estou tentando usar, o useDebounce, está sendo renderizado dentro de um loop:
<Grid sx={{ paddingX: 3 }}>
{forms.length !== 0 && criterias.data.map((data, i) => (
<RecommendationForm
key={data.id}
recommendation={data.recommendation.description}
form={forms.find(f => f.id === data.id)}
onChange={handleChange}
index={i}
onRefetch={onRefetch}
/>
))
}
</Grid>
O que posso fazer para enviar as respostas para meu banco de dados usando esse hook?
Editar: Eu estava usando o useDebounce assim:
const debouncedForm = useDebounce(form, 1000);
const updateRecommendation = Criteria.update();
const submitRecommendation = useCallback(async () => {
try {
const { data } = await updateRecommendation.handle({
variables: {
input: {
conformity: debouncedForm.conformity,
importance: debouncedForm.importance,
comment: debouncedForm.comment,
conclusion: debouncedForm.conformity === 0 && debouncedForm.importance !== null,
},
criteria_id: debouncedForm.id
}
});
return data;
} catch (error) {
console.error("Erro ao atualizar a criteria", error);
}
}, [debouncedForm, updateRecommendation]);
useEffect(() => {
if (debouncedForm) {
submitRecommendation()
}
}, [debouncedForm, submitRecommendation])
Se eu tivesse que adivinhar, seria isto:
Imagino que
submitRecommendation
esteja atualizando o estado do componente e sempre retornando uma nova função, o que está causandouseEffect
a invocação em cada ciclo de renderização (que ele dispara sozinho). Parece quesubmitRecommendation
não deveria estar afetando quando issouseEffect
deveria ser disparado. Se você tiver a regra eslint ativada para isso, ignore-a.