Подтвердить что ты не робот

ReactJS: Как получить доступ к реквизитам дочернего компонента?

Я пишу код в CoffeeScript, так как я пишу React с ним.
Вот основная структура.

{ div, input } = React.DOM

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

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

У меня есть метод toggle для моего класса Outer, который запускается нажатием клавиши быстрого доступа. Он переключает видимость моего приложения.
Когда мое приложение переключается с скрытого на показанный, я хочу сосредоточиться на входе.

Теперь методы переключения выглядят примерно так:

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()

Как мне это сделать?

4b9b3361

Ответ 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 on.

Ответ 3

В этом случае решение прост, вы можете указать ввод автофокусом, который в React фокусирует его, когда он отображается.

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

В общем, вы должны передать опору компоненту Inner, а в componentDidUpdate вы можете сделать:

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