Reputation: 377
After reading React set focus and React focus with timeout I'm still a little bit confused what is the right cross-browser options for setting focus
on input.
I have a problem with conditional rendering inputs which might have focus after rendering in table
, where input
placed in td
.
1)Solution with componentDidUpdate:
//...
componentDidUpdate() {
this.input && this.input.focus();
}
render() {
const show = this.state.isShown;
return (
<td className="editable">
{!show ? (
<input
type="number"
ref={(input) => { this.input = input }}
value={this.state.value}
onBlur={this.save}
onKeyPress={e =>
e.which === 13 || e.keyCode === 13 ? this.save() : null}
/>
) : (
<span onClick={this.onTdClick}>{this.props.name}</span>
)}
</td>
);
}
This solution works in Chrome, IE11, Edge, but does not work in latest Firefox(input event does not appears afterspan
was clicked.
2)Solution with requestAnimationFrame:
//...
componentDidUpdate() {
if (!this.state.isShown) {
requestAnimationFrame(() => {
this.input && this.input.focus();
})
}
}
render() {
// same above
}
This solution works in Chrome, IE11, Edge, but still Firefox does not show input when trying to set focus
.
3)Solution with setTimeout(callback, n):
//...
componentDidUpdate() {
if (!this.state.isShown) {
setTimeout(() => {
this.input && this.input.focus()
}, 50);
}
}
render() {
// same above
}
This case works for Chrome, IE11, Edge and (finally) Firefox, but seems this is the most "ugly" one.
P.S. autoFocus
attr is not for this case, here I have conditional rendering, so need set focus after click.
So, my questions is: have we got a right way to solve this w/o setting setTimeout
for Firefox?
Live testing example: codepen
Upvotes: 5
Views: 2519
Reputation: 417
import React from 'react';
const MyInput = React.createClass({
componentDidMount(){
this.elem.focus();
},
render(){
return(
<input
ref={(elem) => {this.elem = elem}}
type="text"
/>
);
}
});
export default MyInput;
Render <MyInput/>
where you want. After render it will be with focus. Tested on Safari, Chrome, Firefox.
Upvotes: 2