Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

311
Vistas
La entrada no se enfoca cuando se hace clic en el botón

El elemento de entrada no parece enfocarse al hacer clic en un botón en el primer intento, pero luego funciona. No estoy seguro de por qué no se está enfocando en el primer intento, ¿alguien puede ayudar?

Sandbox: https://codesandbox.io/s/enable-the-input-text-field-on-click-of-a-button-forked-ybgtxb?file=/src/index.js

 import React, { useEffect, useRef, useState } from "react"; import { render } from "react-dom"; import * as data from "./messages.json"; const App = () => { return <Test {...{ alreadySetVal1: true, alreadySetVal2: true }} />; }; const Test = ({ alreadySetVal1, alreadySetVal2 }) => { const [input1, setInput1] = useState(alreadySetVal1 ? "Already Set" : ""); const [input2, setInput2] = useState(alreadySetVal2 ? "Already Set" : ""); const [config, setConfig] = useState({ config1: !!input1, config2: !!input2 }); const ref1 = useRef(null); const ref2 = useRef(null); return ( <> <div> <input disabled={config.config1} value={input1} ref={ref1} type={config.config1 ? "text" : "password"} onChange={(e) => setInput1(e.target.value)} /> <span onClick={() => { setInput1(""); setConfig({ ...config, config1: false }); ref1.current.focus(); }} > Enable Input 1 </span> </div> <div> <input disabled={config.config2} value={input2} ref={ref2} type={config.config2 ? "text" : "password"} onChange={(e) => setInput2(e.target.value)} /> <span onClick={() => { setInput2(""); setConfig({ ...config, config2: false }); ref2.current.focus(); }} > Enable Input 2 </span> </div> </> ); }; render(<App messages={data.messages} />, document.getElementById("root"));
about 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Tema

Establecer el enfoque en el primer clic a través de React no funciona porque el elemento de input todavía está deshabilitado.

Solución

Convierta los elementos de span en elementos de label y vincúlelos a su respectivo elemento de input mediante el atributo id . Cuando se hace clic en la etiqueta de las entradas, las entradas reciben el foco.

Ejemplo:

 <div> <input id="input1" // <-- add id attribute disabled={config.config1} value={input1} type={config.config1 ? "text" : "password"} onChange={(e) => setInput1(e.target.value)} /> <label htmlFor="input1" // <-- label for specific input onClick={() => { setInput1(""); setConfig({ ...config, config1: false }); }} > Enable Input 1 </label> </div> <div> <input id="input2" disabled={config.config2} value={input2} type={config.config2 ? "text" : "password"} onChange={(e) => setInput2(e.target.value)} /> <label htmlFor="input2" onClick={() => { setInput2(""); setConfig({ ...config, config2: false }); }} > Enable Input 2 </label> </div>

Editar entrada-no-se-enfoca-cuando-se-hace-clic-en-el-botón

Solución #2

En mi opinión, esto es un poco pirateado, pero si desea usar React ref para establecer el enfoque programáticamente, puede usar setTimeout con una devolución de llamada para establecer el enfoque. El uso de setTimeout colocará la devolución de llamada al final de la cola de eventos y se procesará después de que se haya procesado la actualización del estado de React y se haya vuelto a procesar el componente, lo que hace que la entrada sea enfocable.

Ejemplo:

 <div> <input disabled={config.config1} value={input1} ref={ref1} type={config.config1 ? "text" : "password"} onChange={(e) => setInput1(e.target.value)} /> <span onClick={() => { setInput1(""); setConfig({ ...config, config1: false }); setTimeout(() => { ref1.current.focus(); }); }} > Enable Input 1 </span> </div> <div> <input disabled={config.config2} value={input2} ref={ref2} type={config.config2 ? "text" : "password"} onChange={(e) => setInput2(e.target.value)} /> <span onClick={() => { setInput2(""); setConfig({ ...config, config2: false }); setTimeout(() => { ref2.current.focus(); }) }} > Enable Input 2 </span> </div>

Editar entrada-no-se-enfoca-en-él-cuando-se-hace-clic-en-el-botón (bifurcado)

about 4 years ago · Santiago Trujillo Denunciar

0

import React, { useEffect, useRef, useState } from "react"; import { render } from "react-dom"; import * as data from "./messages.json"; const App = () => { return <Test {...{ alreadySetVal1: true, alreadySetVal2: true }} />; }; const Test = ({ alreadySetVal1, alreadySetVal2 }) => { const [input1, setInput1] = useState(alreadySetVal1 ? "Already Set" : ""); const [input2, setInput2] = useState(alreadySetVal2 ? "Already Set" : ""); const [config, setConfig] = useState({ config1: !!input1, config2: !!input2 }); const ref1 = useRef(null); const ref2 = useRef(null); return ( <> <div> <input disabled={config.config1} value={input1} ref={ref1} type={config.config1 ? "text" : "password"} onChange={(e) => setInput1(e.target.value)} /> <span onClick={async () => { setInput1(""); await Promise.all([ setConfig({ ...config, config1: false }), ]); ref1.current.focus() }} > Enable Input 1 </span> </div> <div> <input disabled={config.config2} value={input2} ref={ref2} type={config.config2 ? "text" : "password"} onChange={(e) => setInput2(e.target.value)} /> <span onClick={async() => { setInput2(""); await Promise.all([ setConfig({ ...config, config2: false }), ]); ref2.current.focus(); }} > Enable Input 2 </span> </div> </> ); }; render(<App messages={data.messages} />, document.getElementById("root"));

Problema: Aquí el problema es que llamas a setConfig({ ...config, config1: false }), AND ref1.current.focus(); en un solo render así que ref1.current.focus(); este enfoque no puede entender los cambios de estado anteriores.

Solución: Entonces, la solución es que necesita un setConfig({ ...config, config1: false }), esta llamada primero y luego llame a ref1.current.focus(); . Aquí la posible solución es usar setTimeout o promise.all . Aquí usopromise.all promise.all es un enfoque comparativamente bueno que usar setTimeout

Puede consultar aquí lo que hace promis.all: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

about 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda