Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Styled component input loses focus onChange

When using an html input with styled-components and saving the value to react state with onChange, the component appears to be re-rendering on every state change and causing the input to lose focus. Is there any way to prevent the input from losing focus? Why is this occurring? Here is an example.

class MyComponent extends React.Component {
  state = { val: "" };

  render() {
    const Input = styled.input`
      border-radius: 6px;
    `;

    return (
      <Input
        value={this.state.val}
        onChange={e => this.setState({ val: e.target.value })}
      />
    );
  }
}
like image 991
jjbskir Avatar asked Jul 18 '19 14:07

jjbskir


People also ask

Why does Input lose focus?

input s provided to Fields as their component props are created anew after every keystroke. This causes them to lose focus, despite having an unique, constant key.

Why does the input field lose focus after typing a character React?

When your onChange event fires, the callback calls setState with the new title value, which gets passed to your text field as a prop. At that point, React renders a new component, which is why you lose focus.

Is styled-components deprecated?

As of styled-components v4 the withComponent API is now a candidate for deprecation. In all likelihood, you probably want to use the new "as" prop to simply switch what element/component being rendered since the withComponent API is destructive toward styles if the lowest-wrapped component is a StyledComponent.

Are styled-components efficient?

Comparing styled-components to Emotion When it comes to writing CSS for JavaScript, both styled-components and Emotion are highly efficient, perform well, and have a dedicated developer base that use each library for specific purposes.


2 Answers

On every render, you generate a new Input therefore loss of focus.

Decouple the style from the component:

const Input = styled.input`
  border-radius: 6px;
`;

class MyComponent extends React.Component {
  state = { val: "" };

  render() {
    return (
      <Input
        value={this.state.val}
        onChange={e => this.setState({ val: e.target.value })}
      />
    );
  }
}

like image 184
Dennis Vash Avatar answered Oct 06 '22 21:10

Dennis Vash


As @Dennis Vash said on every render the component is compiled. Re-compiling the Styled-CSS with is link to the component. Similarly if you used styled components in function. Copy-paste it outside the function so that the variable is created only once

    const CustomInput = styled.input`
       border:none;
       border-radius:0px;
       padding:2px 11px;
       border-bottom:1px solid #ced4da;
       &:focus {
         outline: none;
         border-color:#ced4da;
       }
   `;

   function myFun(props){
         const [value, setvalue] = useState('')
         return (
             <CustomInput 
                value={value}
                onChange={(e)=>setvalue(e.target.value)}
             />
         )
   }
like image 37
NevetsKuro Avatar answered Oct 06 '22 23:10

NevetsKuro