Search code examples
javascriptreactjsfocus

HtmlInput.focus() not working in react.js


I try to code an react app to calculate the typing speed.

I have a problem.

this is some of my code

{  txt &&
   txt.map((c, i) => (
      <Character
         key={i}
         value={c}
         id={"id" + i}
         focus={i === 0 ? true : false}
         index={i}
      />
   ))
}

where txt is the text script like ["L", "o", "r", "e", "m", ...].

each character in the array render the <Character /> component.

This is some of Character.jsx code:

function Character({ value = "-", id, focus, index }) {
    const [char, setChar] = useState("");
    const thisLetter = useRef();

    React.useEffect(() => {
        console.log(thisLetter.current.value);

        if (char) {
            // console.log(thisLetter.nextSibling)
            const next = document.querySelector(`.char:nth-child(${index + 1})`)
            next.focus()
        }
    }, [char]);

    return (
        <input
            ref={thisLetter}
            type="text"
            className="border-none p-0 m-0 fs-250 char"
            style={styles}
            value={char}
            onChange={(e) => setChar((v) => e.target.value)}
            maxLength="1"
            placeholder={value}
            id={id}
            autoFocus={focus}
        />
    );
}

I am so sorry for taking much of your time in above explaining.

My problem is: I want to focus the next sibling component (input) when the current input filed (length > 0)

I tried

thisLetter.current.nextSbling.focus()

but it doesn't work. I also tried

const next = document.querySelector(`.char:nth-child(${index + 1})`)
next.focus()

But it also doesn't work.

How can I focus the next sibling in javascript?

If you want to see the complete code please check Github Repo


Solution

  • I managed to solve the problem and I will put the solution to whoever wants it.

    the problem reason was autoFocus attribute, It was false always. look at this old code: parent component:

    focus={i === 0 ? true : false}
    

    and this in the child component:

    autoFocus={props.focus}
    

    First of all i created state for focus state:

    const [isFocus, setIsFocus] = useState(props.focus);
    

    Then i set autoFocus with the state:

    autoFocus={isFocus}
    

    Then in the validation I made a condition; when the input is validate setIsFocus(false)