skip to Main Content

I tried to make…
There is no input on the screen at the first rendering. When I click the button, input appears. And I want to set focuse on the input at the same time.

Let me explain what i made.
At first, the input is not visible on the screen.
Because the display property of the Box(the div tag), which is the parent component of the input, is none.
But when i click the button, the display property of the Box changes to block.
And here is what i want to do.
i’m going to set focus on the input on the screen.
In the function called when the button is clicked, I wrote a code that changes the css code and sets the focus on the input.
But it didn’t work.
Please take a look at the following code.

const [inputDisplay, setInputDisplay] = useState("none");
const refInput = useRef(null);

const HandleShowInput = () => {
  setInputDisplay("block");
  refInput.current.focus();
};

return (
  <>
    <Box theme={inputDisplay}>
      <Input ref={refInput}/>
    <Box/>
    <Button onClick={HandleShowInput}/>
  </>
)

Below is the code that is dynamically changing the css of the Box component.

import styled, { css } from "styled-components";

const Box = ({ children, ...props }) => {
    return <StBox {...props}>{children}</StBox>;
};

const StBox = styled.div`
  ${({ theme }) => {
    switch (theme) {
      case "block":
        return css`
          display: ${theme} !important;
        `;
      default:
        break;
    }
  }}
`;

export default Box;

But this below code is worked. I separated the code by putting it in useEffect.

const [inputDisplay, setInputDisplay] = useState("none");
const refInput = useRef(null);

const HandleShowInput = () => {
  setInputDisplay("block");
};

useEffect(() => {
    refInput.current.focus();
}, [inputDisplay]);

return (
  <>
    <Box theme={inputDisplay}>
      <Input ref={refInput}/>
    <Box/>
    <Button onClick={HandleShowInput}/>
  </>
)

I want to know why the upper case not works and the lower case works. I don’t know if I have lack react knowledge or css knowledge. I would be very grateful if you could help a beginner in react. Also, please understand if there are any unnatural sentences because i’m not good at English. thank you.

2

Answers


  1. When you are trying to focus on the input element by HandleShowInput this function.Here two things are happening your changing the state and focus of input.It will focus the input but time will be so less that we can’t see on the ui.And also due to the state change render will happen and again ref will get the input element. Thus you are not able to see this focussed input

    But in case of useEffect this will happen after the render. After this no rendering. So we can see the focussed input

    Login or Signup to reply.
  2. The way of thinking about React is a little different from Javascript.

    You may expect the below two run in the same way.

     setInputDisplay("block");
      refInput.current.focus();
    

    and

    document.querySelector('#canFocus').style.display='block'
    document.querySelector('#canFocus').focus();
    

    NO~ It’s not.
    JS block the Dom and then focus it, it works well.
    But React works like the code below.

    setTimeout(()=>{
      // next react render cycle callback
      document.querySelector('#canNotFocus').style.display='block'
    }, 1000)
    document.querySelector('#canNotFocus').focus();
    

    While focus method is called, the dom is display as none;
    You set state in react, ReactDom will make it as a display block in the next life cycle of function component.
    demo here : https://codesandbox.io/s/confident-wilson-q01ktj?file=/index.html

    useEffect(() => {
        refInput.current.focus();
    }, [inputDisplay]);
    

    is a watching function. While inputDisplay changed, the function inside will be called.

    1. you set state to block
    2. react re-render the component as a newer state
    3. render function called, and dom is block
    4. Effect watching function is called and the focus() called.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search