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 })}
/>
);
}
}
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 })}
/>
);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.