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()
Как мне это сделать?
Ответы
Ответ 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()