最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Styled component input loses focus onChange - Stack Overflow

programmeradmin0浏览0评论

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 })}
      />
    );
  }
}

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 })}
      />
    );
  }
}
Share Improve this question edited Jul 18, 2019 at 17:28 jjbskir asked Jul 18, 2019 at 14:28 jjbskirjjbskir 10.6k10 gold badges47 silver badges61 bronze badges 1
  • styled.input creates a new legit react component. It should be defined outside MyComponent. If you intend to define styles exclusively for a particular input without defining a separate component, consider using css prop. – ron4ex Commented Jul 20, 2019 at 8:30
Add a comment  | 

3 Answers 3

Reset to default 18

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 })}
      />
    );
  }
}

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)}
             />
         )
   }

This happens because you've defined Input within the render() method. Every time the state gets updated, the render() method will be called and Input will be redefined and handled as if it was a completely new component (a html <input/> without focus in this case). If you move the definition of Input out of the component, it will work as intended. Also the fragment you've used (</>) in the return of the render() method is kind of pointless.

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 })}
      />
    );
  }
}
发布评论

评论列表(0)

  1. 暂无评论