Estoy trabajando con React en la implementación de un botón en la tabla que ejecuta una solicitud http para decidir si se deshabilita, algo como:
<Table> <tbody> <tr> <td>something1</td> <td>something2</td> <td>something3</td> <Button onClick = {() => DoSomething()} disabled= {Boolean(HTTPRequest(payload))}> Click me! </Button> </tr> </tbody> </Table> function HTTPRequest(payload) { const {loading, error, data} = axios.get(API) return data.length > 0 }Sin embargo, noto que esto no funciona ya que la función se realiza antes de recibir un resultado real. Pensé que tenía algo que ver con la asincronía, así que lo cambié a:
async function HTTPRequest(payload) { const {loading, error, data} = await axios.get(API) return data.length > 0 }Pero todavía no funciona. Cualquier sugerencia será apreciada, ¡gracias!
Como lo hizo, necesitaría un estado que esté fuera de la función HTTPRequest . Algo como esto:
const [loading, setLoading] = useState(false); async function HTTPRequest(payload) { setLoading(true); const {loading, error, data} = await axios.get(API) setLoading(false); } <Button onClick = {() => DoSomething()} disabled={loading}> Click me! </Button> Podría usar un botón personalizado dentro de la Table , primero CustomButton y expórtelo:
import Button from 'react-bootstrap/Button'; import {useEffect,useState} from "react"; const CustomButton = ({payload, clickHandler, children})=>{ const [loading, setLoading] = useState(false); useEffect(()=>{ async function HTTPRequest(payload) { setLoading(true); const {loading, error, data} = await axios.get(API) setLoading(false); } }, [payload]) return ( <Button onClick = {() => clickHandler()} disabled={loading}> {children} </Button> ) } export default CustomButton; <Table> <tbody> <tr> <td>something1</td> <td>something2</td> <td>something3</td> <CustomButton clickHandler = {DoSomething} payload={payload}> Click me! </CustomButton> </tr> </tbody> </Table>El atributo "deshabilitado" no se supone que ejecute una función.
Debe ejecutar la función en el montaje del componente y agregar el estado para actualizar la interfaz de usuario.
Ex;
const [disabled, setDisabled] = useState(false); async function HTTPRequest(payload) { const {loading, error, data} = await axios.get(API) setDisabled(data.length > 0) } useEffect(() => {(async () => await HTTPRequest())()}, [])Creo que el camino a seguir es usar un estado y un efecto.
const [bool, setBool] = useState(initialBoolStateWanted); useEffect(()=>{ (async()=>{ let data = await axios.get(API) setBool(data.length > 0) })() },[]) return( <Button onClick = {() => DoSomething()} disabled={bool}> Click me! </Button> )Editar: agregado a la solución para comentar
Si necesitas hacer varias solicitudes
const [bools, setBools] = useState([initialBoolStateWanted]); useEffect(()=>{ (async()=>{ let datas = await Promise.all( //For each button give different props to the request bools.map((elem, index) => axios.get(API(index)) ) setBools(datas.map(elem => elem.length > 0)) })() },[]) return( <Button onClick = {() => DoSomething()} disabled={bool}> Click me! </Button> )Si puede hacerlo en una sola solicitud que devuelve una matriz
const [bools, setBools] = useState([initialBoolStateWanted]); useEffect(()=>{ (async()=>{ let datas = await axios.get(API) setBools(datas.map(elem => elem.length > 0)) })() },[]) return( <Button onClick = {() => DoSomething()} disabled={bool}> Click me! </Button> )O haga un componente de botón que maneje su propio estado