Me gustaría usar un enlace de solicitud de API personalizado como ese
// hooks.js import { useState, useEffect } from 'react'; import api from '../utils/api'; function useAPI(fn, payload) { const [state, setState] = useState({ loading: false, data: null, error: null, }); const callAPI = async () => { const setAPIState = update => setState({ ...state, ...update }); try { setAPIState({ loading: true }); const data = await fn(payload); setAPIState({ data, loading: false }); } catch (error) { setAPIState({ error, loading: false }); } }; useEffect(() => { callAPI(); }, [fn, payload]); return state; } export const useFetchTransactions = payload => { const fetchTransactions = api.fetchTransactions; return useAPI(fetchTransactions, payload); };y llamarlo dentro de mi componente React así:
// Component.jsx import { useState } from 'react'; import { useFetchTransactions } from '../hooks.js'; export default const Component = () => { const [id, setID] = useState(''); const [date, setDate] = useState('12/13/21'); const { loading, data, error } = useFetchTransactions({ id, date }); return ( <div>{data.map...}</div> ) } Sin embargo, esto se ve mal. Creo que useFetchTransactions debería vivir dentro de un useEffect, de modo que el componente se convierta en algo como:
// Updated Component.jsx import { useState, useEffect } from 'react'; import { useFetchTransactions } from '../hooks.js'; export default const Component = () => { const [id, setID] = useState(''); const [date, setDate] = useState('12/13/21'); const [apiState, setApiState] = useState({ data: null, error: null, loading: false }) useEffect(() => { const result = useFetchTransactions({ id, date }); setState({ ...apiState, ...result }); }, [date, id]) return ( <div>{apiState.data.map...}</div> ) }Pero lo anterior se siente engorroso y redundante. ¿Puede alguien por favor prestar algún conocimiento sobre esto? ¡Gracias!
Puedes hacerlo así
function useAPI(fn) { const [state, setState] = useState({ loading: false, data: null, error: null, }); const callAPI = async (payload) => { const setAPIState = update => setState({ ...state, ...update }); try { setAPIState({ loading: true }); const data = await fn(payload); setAPIState({ data, loading: false }); } catch (error) { setAPIState({ error, loading: false }); } }; return {state, callAPI}; } export const useFetchTransactions = () => { const fetchTransactions = api.fetchTransactions; return useAPI(fetchTransactions); };Y luego en tu componente
import { useState } from 'react';
import { useFetchTransactions } from '../hooks.js';
export default const Component = () => {
const [id, setID] = useState('');
const [date, setDate] = useState('12/13/21');
const { callAPI, loading, data, error } = useFetchTransactions(); useEffect(() => { callAPI({ id, date }) }, [date, id])
return (
<div>{data.map(callAPI)}</div>
)
}