这是一个很容易遇见的问题,每输入一个字符Input的焦点就没了,本文将就此问题做分析和介绍一种解决方法。
出现的原因可能是你在组件的render函数中用了通过函数生成的Input组件,具体请看分析。
如果你遇见该种问题时并没有使用函数式组件,请告知,并一起思考解决方案。
本文涉及的现象及常见的原因
一般情况下在react框架下使用Input组件时,不管是跟着教程或者是网络搜索的用法,常见如下:
export default class Test extends Component {
onChange=(e)=>{
this.setState({
value: e.target.value,
})
}
render() {
return (
<div>
<Input onChange={this.onChange} value={this.state.value}></Input>
</div>
)
}
}
纵观搜索到的资料,基本都是这种用法,这种用法当然没问题,是一种很标准的用法,但是当它遇到函数式组件的时候会出现每次输入都会失去焦点的问题,
函数式组件?
render() {
let input = <Input onChange={this.onChange} value={this.state.value}></Input>
return (
<div>
{input}
</div>
)
}
就是说当你的组件中需要用逻辑来控制渲染什么组件的时候会用一个变量指向一个函数,该函数返回一个组件,这个逻辑中可能会有switch或者若干个if语句。
此时!每次render的时候,相当于都要调用这个函数来重新生成一个组件用于渲染,也就是说这时候的组件已经不是上次渲染出的组件了,当然会出现这种没有焦点的情况了。
解决方案
如果你看到了这里,说明你确实使用了函数式组件,在这种情况下,你可以参考下文中的方案,希望可以有所帮助。
有些文章提出的解决方案是不要用函数式组件,这不就是经典的“既然解决不了问题,就解决制造问题的人”的例子嘛?目前可供参考的解决方案如下:
export default class Test extends Component {
onChange=(e)=>{
this.inputValue = e.target.value;
}
onBlur=()=>{
this.setState({
value: this.inputValue,
})
}
render() {
return (
<div>
<Input
onChange={this.onChange}
// 在失去焦点的时候再setState,如果业务允许增加一个按钮,也可以放在按钮的click事件里
onBlur={this.onBlur}
// 这种方法在setState之后,重新生成的Input组件里面的内容就没了,可以用defaultValue重新加载上次的值。
defaultValue={this.state.value}
></Input>
// 如果业务允许增加一个按钮的话,可以把setState方法放在按钮的click事件里。
<Button onClick={this.onBlur}>提交</Button>
</div>
)
}
}
一种曲线救国的方案吧,但是总体思路就是,如果无可避免地要使用函数式组件的话,在向Input组件里输入内容的过程中不要让它触发render,把这个触发操作放在输入结束后,手动的点击按钮或者待它失去焦点。
以上。希望能有所帮助。
If the world leaving nothing but one, that must be the love.