Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

310
Visualizações
Input doesnt get focus on it when button is clicked

The input element doesnt seem to get focused on click of a button on the first go, But later on it is working. Not sure why it is not being focused on the first go, can some one help

Sandbox: https://codesandbox.io/s/enable-the-input-text-field-on-clicking-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 Respostas
Responde à pergunta

0

Issue

Setting the focus on the first click via React doesn't work because the input element is currently still disabled.

Solution

Convert the span elements to label elements and link them to their respective input element by id attribute. When the label for inputs are clicked the inputs receive the focus.

Example:

<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>

Edit input-doesnt-get-focus-on-it-when-button-is-clicked

Solution #2

This is a bit hackish IMO, but if you want to use the React ref to programatically set the focus then you can use a setTimeout with a callback to set the focus. Using the the setTimeout will place the callback at the end of the event queue and be processed after the React state update has been processed and the component rerendered, thus making the input focusable.

Example:

<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>

Edit input-doesnt-get-focus-on-it-when-button-is-clicked (forked)

about 4 years ago · Santiago Trujillo Relatório

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"));

Problem: Here problem is you call setConfig({ ...config, config1: false }), AND ref1.current.focus(); in a single render so ref1.current.focus(); this focus can't understand is previous state changes.

Solution: So, solution is you need a complete setConfig({ ...config, config1: false }), this call first then call ref1.current.focus(); . Here possible solution is either you use setTimeout or promise.all. Here I use promise.all because promise.all is comparatively good approach than using setTimeout

You can check here what promis.all do: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda