2014-06-21 3 views
22

Я пишу код в CoffeeScript, так как я писал об этом.
Вот основная структура.ReactJS: Как получить доступ к реквизитам дочернего компонента?

{ div, input } = React.DOM 

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

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

У меня есть 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() 

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

ответ

25

Доступ к 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

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

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

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

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

AutoFocus не работает для меня. На самом деле я просто подумал о 'componentDidUpdate' и попробовал нечто похожее на то, что вы предложили, и это сработало. Но я действительно хочу знать, есть ли простой способ доступа к реквизитам дочерних компонентов. Пример refs в React Doc вводит ввод в верхний компонент, но на самом деле входы обычно вложены в подкомпоненты. – octref

+0

Refs могут использоваться только в компоненте, где они определены. Если бы они были доступны любому дочернему компоненту, вы должны были бы предположить, что ваше имя для ссылки не будет конфликтовать с любым другим ref. Вам также нужно будет проверить каждый другой компонент, если вы хотите удалить ссылку или изменить ее. Эти предположения и смотреть повсюду лучше избегать. – FakeRainBrigand

3

Вы можете цепи рефов, так что если вы тянете элемент по реф, вы можете захватить реф внутри этого элемента:

Определения вашего Outer класса как Outer = React.createClass render: -> div { id: 'myApp' }, Inner {ref: 'inner'}

пусть будет вы затем берете вход с @refs.inner.refs.myInput.getDOMNode(), чтобы позвонить по телефону focus.

+1

Спасибо за ваш ответ, но я предпочитаю решение @ssorallen, которое выглядит чище для меня. – octref

Смежные вопросы