在条件渲染中使用refs

hug*_*ent 3 javascript reference reactjs

我在ref和条件渲染方面遇到问题。单击按钮标签时,我想聚焦输入标签。基本上,我有这个简化的代码。

class App extends React.Component {
  textInput
  constructor(props) {
    super(props)
    this.state = {isEditing: false}
    this.textInput = React.createRef()
  }

    onClick = () => {
        this.setState({isEditing: !this.state.isEditing})
        this.textInput.current.focus();
    }
  render () {
    let edit = this.state.isEditing ?
        (<input type="text" ref={this.textInput} />)
        : ""
    return (
      <div>
            <button onClick={this.onClick}>lorem </button>
            {edit}
      </div>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

当我单击按钮时,显示输入标签,但参考textInput仍设置为null。因此,我无法集中精力进行输入。

我发现了一些解决方法,例如:

  • autoFocus在输入标签中设置属性
  • 当使用css隐藏输入标签时 isEditing == false

但这实际上是一个非常基本的模式,我想知道是否有一个干净的解决方案。

谢谢

ros*_*dia 7

TL; DR:

更改此:

this.setState({isEditing: !this.state.isEditing})
this.textInput.current.focus();
Run Code Online (Sandbox Code Playgroud)

对此:

this.setState(state => ({isEditing: !state.isEditing}), () => {
    this.textInput.current.focus();    
});
Run Code Online (Sandbox Code Playgroud)

细节:

您遇到了很多人遇到的React常见问题,这是假设设置状态是同步的。不是。调用setState时,您是在请求 React更新状态。实际状态更新稍后发生。这意味着在setState调用之后,该edit元素尚未立即创建或呈现,因此ref指向null

文档

setState()将组件状态更改入队,并告知React该组件及其子级需要使用更新后的状态重新呈现。这是用于响应事件处理程序和服务器响应而更新用户界面的主要方法。

将其setState()视为更新组件的请求而不是立即命令。为了获得更好的感知性能,React可能会延迟它,然后在一次通过中更新几个组件。React不保证状态更改会立即应用。

setState()并不总是立即更新组件。它可能会批量更新或将更新推迟到以后。这样可以this.statesetState()潜在的陷阱后立即阅读。而是使用componentDidUpdatesetState回调(setState(updater, callback)),保证在应用更新后都会触发两者。

  • @rossipedia,虽然您的方法仍然很好,但我建议您在此处使用功能性的`setState()`,因为新状态取决于上一个状态。这也是官方文档推荐的方法。 (2认同)