Estoy tratando de crear elementos de interfaz de usuario dinámicos usando reaccionar y he creado un bucle de elementos al mapear sobre una matriz y al hacer clic en el elemento, pasa los valores a una función. Mi código se ve algo como a continuación
const [shortlistedIds, setShortlistedIds] = useState([]); const attachmentInputRef = useRef(); const handleOpenFilePicker = async () => { attachmentInputRef.current.click(); }; //somewhere in code, set the IDs setShortlistedIds(["1", "2", "3", "4"]); const handleFilePicker = async(e) => { console.log(e.target.id) let uploadFiles = [...e.target.files] const apiRes = await api.createAttachment(e.target.id, uploadFiles) } return( {shortlistedIds.map((myId) => ( <button id={myId} className="attachment-button pull-right" onClick={handleOpenFilePicker} style={{ position: "absolute" }} > click me {myId} </button> <input id={myId} ref={attachmentInputRef} type="file" style={{ display: "none" }} name="file" onChange={(e) => {handleFilePickerChange(myId, e);}} multiple /> ) )}; )El html se procesa correctamente con la identificación y el texto correctos para cada botón, pero al hacer clic, el valor impreso en la consola desde handleFilePicker es siempre la última identificación, "4" del ejemplo anterior, sin importar en qué botón haga clic. No estoy seguro de cuál es el problema aquí. (Ignore cualquier error tipográfico, ya que este es un código de ejemplo basado en el código real. No es factible pegar el código real aquí)
Hazlo simple
const [shortlistedIds, setShortlistedIds] = useState([]); useEffect(() => { setShortlistedIds(["1", "2", "3", "4"]); }, []) const targetClick = (e)=>{ console.log(e); } return ( { shortlistedIds.map(myId => { return(<button onClick={() =>targetClick(myId)} key={myId}>click me{myId}</button>) }) } )El problema en el caso anterior es que useRef() apunta a una referencia y por lo tanto, al reasignarla cambia el valor cada vez que se asigna en el mapa, asignándose finalmente al valor final. El gancho useRef() no se replica con cada asignación en el campo de entrada.
Para resolver esto, moví el bloque de entrada a un componente secundario que creó un useRef() para cada uno de los campos de entrada y, por lo tanto, funciona bien.
Debe pasar la clave de atributo = {myid} en su elemento de botón.