A continuación se muestra mi gancho personalizado, estoy tratando de manejar todo desde el gancho. He visto preguntas similares, pero ninguna parece funcionar para mi caso y me han hecho creer que hay una solución para este enfoque, simplemente no puedo resolverlo.
const useResource = (baseUrl) => { const [resources, setResources] = useState([]); const create = async (resource) => { const response = await axios.post(baseUrl, resource) setResources(resources.concat(response.data)); console.log(resources) return response.data } const get = async () => { const response = await axios.get(baseUrl); setResources(response.data) return response.data } const service = { create, get } return [ resources, service ] }Este es mi enfoque para usar el gancho personalizado, pero la solicitud sigue en bucle sin parar, ¿cómo detengo que se ejecute después de cada procesamiento?
const App = () => { const content = useField('text'); const name = useField('text'); const number = useField('text'); const [notes, noteService] = useResource('http://localhost:3005/notes'); const [persons, personService] = useResource('http://localhost:3005/persons'); useEffect(() => { noteService.get(); }, [noteService]) useEffect(() => { personService.get(); }, [personService]) const handleNoteSubmit = (event) => { event.preventDefault(); noteService.create({ content: content.value }); } const handlePersonSubmit = (event) => { event.preventDefault(); personService.create({ name: name.value, number: number.value}); }Editar: solo tuve que deshabilitar ESLint para la línea de dependencia, porque solo necesito que se ejecute una vez después de cada procesamiento. ¡Funciona bien!
useEffect(() => { noteService.get(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []) useEffect(() => { personService.get(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [])Como se señaló correctamente en los comentarios, cada vez que el componente representa y llama a su useResource , se crea un nuevo objeto de service . Si este objeto de service se usa como una dependencia para cualquier otro gancho, esto activará sus devoluciones de llamada.
La solución es memorizar el objeto de service para que se proporcione como una referencia estable. Esto se puede lograr a través del useMemo . Debido a que el service se memorizará, la devolución de llamada de create también se memorizará y contendrá el estado de resources obsoletos. Para abordar esta actualización, create para usar una actualización de estado funcional al agregar nuevos datos de respuesta al estado existente.
Ejemplo:
import { useEffect, useMemo, useState } from 'react'; const useResource = (baseUrl) => { const [resources, setResources] = useState([]); const create = async (resource) => { const response = await axios.post(baseUrl, resource); // Functional update to update from previous state setResources(resources => resources.concat(response.data)); return response.data; } const get = async () => { const response = await axios.get(baseUrl); setResources(response.data); return response.data; } const service = useMemo(() => ({ create, get }), []); return [resources, service]; };