He creado un formulario y tengo dos botones de envío. Ahora estoy tratando de guardar el valor del botón para hacer dos llamadas API diferentes basadas precisamente en el valor del botón.
Mi problema es que a veces el valor del botón resulta "indefinido", por lo que cuando se hace clic en él, no sucede nada.
return ( <AvForm model={{}} onSubmit={saveEntity}> //..... <Button id="pdf" replace color="info" data-cy="entityCreatePDF" type="submit" onClick={buttonClicked} value="pdf"> <FontAwesomeIcon icon="save" /> <span className="d-none d-md-inline"> PDF </span> </Button> <Button color="primary" id="csv" data-cy="entityCreateCSV" type="submit" onClick={buttonClicked} value="csv"> <FontAwesomeIcon icon="save" /> <span className="d-none d-md-inline"> CSV </span> </Button> ) const buttonClicked = event => { console.log('event target', event.target.value); setButtonClick(event.target.value); }; const saveEntity = (event, errors, values) => { //.... filteredEntities(params, sorting) } const filteredEntities = (params, sort) => { console.log('-- buttonClick --', buttonClick); // there sometimes I receive undefined and so it doesn't enter in the if if (buttonClick === 'pdf') { getReportPDF(params, sort); } if (buttonClick === 'csv') { getReportCSV(params, sort); } }Hay algo que debo hacer para evitar este comportamiento (es decir, que la clave da como resultado un valor indefinido y, por lo tanto, no me permite realizar ninguna acción).
Gracias
Respuesta corta:
Reemplazar
const buttonClicked = event => { console.log('event target', event.target.value); setButtonClick(event.target.value); };con
const buttonClicked = event => { console.log('event target', event.currentTarget.value); setButtonClick(event.currentTarget.value); };¿Por qué? A veces, hace clic en el botón en sí, a veces, por ejemplo, en el icono dentro de él: el elemento en el que hace clic es en realidad un "objetivo". Sin embargo, "currentTarget" permite el uso del elemento al que se asignó el detector de eventos.
Este problema podría deberse a que setState es asíncrono, es decir, el estado no cambia inmediatamente después de llamar a setButtonClick . Puede usar una referencia para eludir este problema, si no necesita volver a renderizar cuando se cambia buttonClick , y use buttonClick.current para obtener el valor.
const buttonClick = useRef(); ... const buttonClicked = event => { console.log('event target', event.target.value); buttonClick.current = event.target.value; }; ... const filteredEntities = (params, sort) => { console.log('-- buttonClick --', buttonClick.current); if (buttonClick.current === 'pdf') { getReportPDF(params, sort); } if (buttonClick.current === 'csv') { getReportCSV(params, sort); } }Si necesita volver a renderizar cuando cambia, use el estado y una referencia.
Puede guardar directamente el valor en el estado. Como no es un campo de entrada, no es necesario tratar con event.target.value
..... <Button onClick={() => setButtonClick('csv')} <Button onClick={() => setButtonClick('pdf')}