Estoy buscando la forma más óptima de obtener datos usando useEffect() cuando la función de obtención se usa en más de un lugar.
Actualmente, tengo un componente principal ( ItemContainer ) y un componente secundario ( SearchBar ). ItemContainer debe obtener toda la lista posible de elementos utilizando las funciones getItemList() . Estoy ejecutando esta función dentro de useEffect() durante el primer procesamiento, y también la paso al componente SearchBar , de modo que cuando un usuario envíe un término de búsqueda, actualizará el estado de itemList activando getItemList() en ItemContainer .
Esto realmente funciona tal como esperaba. Sin embargo, mi problema es que
getItemList() fuera de useEffect() en este tipo de situación. Por lo que he estado leyendo (publicaciones de blog, documentos oficiales de reacción), generalmente se recomienda que la función de obtención de datos se defina dentro de useEffect() , aunque podría haber algunos casos extremos. Me pregunto si mi caso se aplica como este caso de borde.useCallback ? Intenté completarlo usando searchTerm , itemList , pero ninguno de ellos funcionó, y estoy bastante confundido por qué es así.Me siento mal porque no entiendo completamente el código que escribí. Agradecería si alguno de ustedes pudiera iluminarme con lo que me estoy perdiendo aquí...
const ItemContainer = () => { const [itemList, setItemList] = useState([]); const getItemList = useCallback( async (searchTerm) => { const itemListRes = await Api.getItems(searchTerm); setItemList(itemListRes) }, []); useEffect(() => { getItemList(); }, [getItemList]); return ( <main> <SearchBar search={getItemList} /> <ItemList itemList={itemList} /> </main> ) } const SearchBar = ({ search }) => { const [searchTerm, setSearchTerm] = useState(''); const handleSubmit = (e) => { e.preventDefault(); search(searchTerm); setSearchTerm(''); } const handleChange = (e) => { setSearchTerm(e.target.value) } return ( <form onSubmit={handleSubmit}> <input placeholder='Enter search term...' value={searchTerm} onChange={handleChange} /> <button>Search</button> </form> ) }Aquí están mis respuestas.
Sí, está bien. Lo que hay dentro de useCallback está "congelado" con respecto a las muchas llamadas a la función ItemConteiner que pueden ocurrir. Dado que el contenido de useCallback solo accede a setItemList , que también es un controlador congelado, no habrá problemas.
Eso también es correcto, porque una matriz vacía significa "dependiente de nada". En otras palabras, la devolución de llamada se crea una vez y se mantiene congelada durante toda la vida del ItemContainer .
En cambio, esto es algo raro:
useEffect(() => { getItemList(); }, [getItemList]); Funciona, pero tiene muy poco sentido. El getItemList se crea una sola vez, entonces, ¿por qué hacer un useEffect dependiendo de que algo nunca cambie?
Hágalo más simple, ejecutando solo una vez:
useEffect(() => { getItemList(); }, []);