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

177
Visualizações
How to focus the next input with React

I'm creating a game like wordle and, to do this, when the user writes a letter, the app should focus the next input. I can't do this, and I don't know why.

    
const GameLine = (props) => {

    const lineIndex = props.index;
  
    const checkTry = () => {
        const userGuess = firstLetter + ' ' + secondLetter + ' ' + thirdLetter + ' ' + fourthLetter + ' ' + fifthLetter;
        console.log(userGuess);
    }

    const [firstLetter, setFirstLetter] = useState(null);
    const [secondLetter, setSecondLetter] = useState(null);
    const [thirdLetter, setThirdLetter] = useState(null);
    const [fourthLetter, setFourthLetter] = useState(null);
    const [fifthLetter, setFifthLetter] = useState(null);
  
    const handleNextInput = (e) => {
        console.log("ID atual: " + e.target.id);
        const fieldName = e.target.id.split('-')[1];
        const nextSibiling = document.getElementById(`box${lineIndex}-${parseInt(fieldName) + 1}`);
        console.log(nextSibiling);
        if(nextSibiling !== null){
            nextSibiling.focus();
        }
    }


    return ( 
        <BoxesDiv>
            <Box1 type="text" id={ `box${lineIndex}-1`} onChange={(e) => { handleNextInput(e); setFirstLetter(e.target.value)}} value={firstLetter} /> 
            <Box2 type="text" id={ `box${lineIndex}-2`} onChange={(e) => setSecondLetter(e.target.value)} value={secondLetter} onKeyPress={(e)=>handleNextInput(e)}/>
            <Box3 type="text" id={ `box${lineIndex}-3`} onChange={(e) => { handleNextInput(e); setThirdLetter(e.target.value)}} value={thirdLetter} /> 
            <Box4 type="text" id={ `box${lineIndex}-4`} onChange={(e) => { handleNextInput(e); setFourthLetter(e.target.value)}} value={fourthLetter} />
            <Box5 type="text" id={ `box${lineIndex}-5`} onChange={(e) => setFifthLetter(e.target.value)} value={fifthLetter} onKeyPress={ (e)=>{ if(e.key === "Enter"){checkTry()} } }/>
        </BoxesDiv>  
    );
}

I'm trying to get the next input with id and use Element.focus(), but nothing happens. Could someone help me to find where's my error?

Thanks

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

You should called handleNextInput function for second box. I think you could onKeyUp function for handleNextInput.

<Box2 onKeyUp={(e)=>handleNextInput(e)} ... />
about 4 years ago · Juan Pablo Isaza Relatório

0

React's way of accessing elements is to use refs. You can create an array of refs initially and map them to the inputs. Add a keyup event listener to update the input focus to the next input.

Try like below.

import { useState, createRef, useEffect } from "react";

const GameLine = (props) => {
  const lineIndex = props.index;
  // number of inputs
  const numerOfInputs = props?.numerOfInputs || 5;

  // create a array of refs
  const [inputRefsArray] = useState(() =>
    Array.from({ length: numerOfInputs }, () => createRef())
  );

  // state for current input index
  const [currentIndex, setCurrentIndex] = useState(0);

  // save letters in a array where each entry in the array refers to an input
  const [letters, setLetters] = useState(() =>
    Array.from({ length: numerOfInputs }, () => "")
  );

  const handleKeyPress = () => {
    setCurrentIndex((prevIndex) => {
      // calculate the next input index, next input after the final input will be again the first input. you can change the logic here as per your needs
      const nextIndex = prevIndex < numerOfInputs - 1 ? prevIndex + 1 : 0;
      const nextInput = inputRefsArray?.[nextIndex]?.current;
      nextInput.focus();
      nextInput.select();
      return nextIndex;
    });
  };

  useEffect(() => {
    // focus the firs iput initially
    if (inputRefsArray?.[0]?.current) {
      inputRefsArray?.[0]?.current?.focus();
    }
    
    // add the event listener for keyup keyboard event
    window.addEventListener("keyup", handleKeyPress, false);
    
    // remove the event listener when the component unmounts
    return () => {
      window.removeEventListener("keyup", handleKeyPress);
    };
  }, []);

  return (
    <div>
      {inputRefsArray.map((ref, index) => {
        return (
          <input
            ref={ref}
            type="text"
            id={`box${index}-1`}
            onChange={(e) => {
              const { value } = e.target;
              setLetters((letters) =>
                letters.map((letter, letterIndex) =>
                  letterIndex === index ? value : letter
                )
              );
            }}
            onClick={(e) => {
              setCurrentIndex(index);
              e.target.select();
            }}
            value={letters[index]}
            max={"1"}
          />
        );
      })}
    </div>
  );
};

export default GameLine;

Edit ecstatic-franklin-m94ci0

about 4 years ago · Juan Pablo Isaza 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