【问题标题】:ReactJS: How to access refs of child component?ReactJS:如何访问子组件的引用?
【发布时间】:2014-08-11 22:41:48
【问题描述】:

我一直在用 CoffeeScript 编写代码,因为我一直在用它编写 React。
这是基本结构。

{ div, input } = React.DOM

Outer = React.createClass
  render: ->
    div { id: 'myApp' },
      Inner()

Inner = React.createClass
  render: ->
    input { id: 'myInput', ref: 'myInput' }

我的 Outer 类上有一个 toggle 方法,该方法是通过按下快捷键触发的。它会切换我的应用的可见性。
当我的应用从隐藏切换到显示时,我想专注于输入。

现在切换方法看起来或多或少像这样:

Outer = React.createClass
  render: ->
     ......

  hide: ->
    @setState { visible: no }

  show: ->
    @setState { visible: yes }

    $('#myInput').focus() # jQuery
    # I want to do something like
    # @refs.myInput.getDOMNode().focus()
    # But @refs here is empty, it doesn't contain the refs in Inner

  toggle: ->
    if @state.visible
      @hide()
    else
      @show()

那我该怎么做呢?

【问题讨论】:

    标签: coffeescript reactjs


    【解决方案1】:

    访问子组件的 refs 会破坏封装,因为 refs 不被视为组件 API 的一部分。相反,您应该在 Inner 上公开一个可由父组件调用的函数,将其称为 focus 可能有意义。

    另外,聚焦componentDidUpdate中的元素以确保渲染完成:

    { div, input } = React.DOM
    
    Outer = React.createClass
      render: ->
        div { id: 'myApp' },
          Inner({ref: 'inner'})
    
      componentDidUpdate: (prevProps, prevState) ->
        # Focus if `visible` went from false to true
        if (@state.visible && !prevState.visible)
          @refs.inner.focus()
    
      hide: ->
        @setState { visible: no }
    
      show: ->
        @setState { visible: yes }
    
      toggle: ->
        if @state.visible
          @hide()
        else
          @show()
    
    Inner = React.createClass
      focus: ->
        @refs.myInput.getDOMNode().focus()
    
      render: ->
        input { id: 'myInput', ref: 'myInput' }
    

    【讨论】:

      【解决方案2】:

      你可以链式引用,所以如果你通过引用拉取一个元素,你可以在那个元素内部抓取引用:

      将您的 Outer 类定义为 Outer = React.createClass render: -> div { id: 'myApp' }, Inner {ref: 'inner'}

      然后让您使用@refs.inner.refs.myInput.getDOMNode() 获取输入以调用focus

      【讨论】:

      • 感谢您的回答,但我更喜欢 @ssorallen 的解决方案,它对我来说看起来更干净。
      【解决方案3】:

      在这种情况下,解决方案很简单,您可以将输入设置为自动对焦,在 React 中,它会在渲染时对其进行对焦。

      Inner = React.createClass
        render: ->
          input { ref: 'myInput', autoFocus: true }
      

      一般来说,你应该给Inner组件传递一个prop,在componentDidUpdate你可以这样做:

      if @props.something
          @refs.myInput.getDOMNode().focus()
      

      【讨论】:

      • 自动对焦对我不起作用。实际上,我只是想到了componentDidUpdate,并尝试了与您建议的类似的方法,并且奏效了。但我真的很想知道是否有一种简单的方法可以访问子组件的引用。 React Doc 上的 refs 示例将输入放在顶部组件中,但实际上输入通常嵌套在子组件中。
      • Refs 只能在定义它们的组件中使用。如果任何子组件都可以访问它们,则您必须假设您的 ref 名称不会与任何其他 ref 冲突。如果您想删除 ref 或更改它,您还必须检查所有其他组件。最好避免这些假设和四处张望。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-05
      • 2014-04-05
      • 2014-09-02
      • 1970-01-01
      • 2019-08-01
      • 1970-01-01
      • 2015-04-02
      相关资源
      最近更新 更多