Estoy creando una interfaz para una API que requiere que un usuario ingrese tanto una clave de API como un nombre de dispositivo. El problema es que la búsqueda de UseEffect() se activa con 'indefinido' como la clave API en el procesamiento, por lo que la API genera un código de error 401 y evita que la página se procese para que el usuario pueda ingresar una clave.
Vea el siguiente código:
const Api = ({ device, key }) => { const [data, setData] = useState(null); useEffect(() => { fetch(`APILINK&key=${key}&id=${device}`) .then((res) => res.json()) .then(setData) }, [device, key]) if (data) return ( <> <tbody> <tr> <th>Date</th> <th>Temp</th> <th>C02</th> </tr> {data.samples.map((item) => ( <tr> <td>{item.time}</td> <td>{item.data[0]}</td> <td>{item.data[1]}</td> </tr> ))} </tbody> </> ) return <div>No Data Found</div> } const Home = ({ setDevice, setKey }) => { const getData = (e) => { e.preventDefault(); const newDevice = e.target.deviceID.value; const apiKey = e.target.apiKey.value; setDevice(newDevice); setKey(apiKey); } return ( <> <h1>Type in a device and provide an API key below:</h1> <form onSubmit={getData}> <input type='text' placeholder="Enter Device..." id='deviceID'></input> <input style={{display: 'block'}} type='text' placeholder="Enter API Key..." id='apiKey'></input> <button>Search</button> </form> </> ) } export default Home; const App = () => { const [device, setDevice] = useState() const [key, setKey] = useState() return ( <> <Home setDevice={setDevice} setKey={setKey} /> <Api device={device} key={key} /> </> ) } export default App;¡Cualquier ayuda es apreciada!
Puede esperar hasta que la key y los accesorios del device estén disponibles:
useEffect(() => { key && device && fetch(`APILINK&key=${key}&id=${device}`) .then((res) => res.json()) .then(setData) }, [device, key]) useEffect se llama justo después del primer procesamiento, independientemente de la matriz de dependencia, por lo que esta protección anterior no ejecutará la llamada de fetch hasta que esas variables estén disponibles (cuando la matriz de dependencia "ve" que hubo un cambio y llama a la devolución de llamada useEffect ).
Es posible que desee mostrar un cargador si el apoyo key puede tardar un tiempo en estar disponible.
Sugiero desacoplar la lógica que obtiene los datos de useEffect , porque es posible que desee llamar a getData directamente, y también es mejor para las pruebas y el orden general del código.
const getData = (key, device) => key && device && fetch(`APILINK&key=${key}&id=${device}`) .then((res) => res.json()) .then(setData); useEffect(() => { getData(key, device) }, [device, key]) Además, no hay necesidad de null en useState(null) , porque useState() se comportará de manera idéntica.
Puede poner su búsqueda dentro de la declaración if
useEffect(() => { if(key && device){ fetch(`APILINK&key=${key}&id=${device}`) .then((res) => res.json()) .then(setData) } }, [device, key])Si su intención es cargar datos en el procesamiento y no cargar más después de eso, haría los siguientes cambios en su enlace useEffect:
useEffect(() => { if(!device || !key || data) return null fetch(`APILINK&key=${key}&id=${device}`) .then((res) => res.json()) .then(setData) }, [data, device, key])