react ref with focus() не работает без setTimeout (мой пример)

я столкнулся с этой проблемой,.focus() работает только с setTimeout если я возьму его, и он перестанет работать. может кто-нибудь объяснить мне, в чем причина, возможно я делаю неправильно и как я могу исправить эту проблему.

    componentDidMount() {
        React.findDOMNode(this.refs.titleInput).getElementsByTagName('input')[0].focus();
    }

работает пример с setTimeout

componentDidMount() {
    setTimeout(() => {
        React.findDOMNode(this.refs.titleInput).getElementsByTagName('input')[0].focus();
    }, 1);
}

JXS

<input ref="titleInput" type="text" />

и я последовал этому примеру React установить фокус на вход после рендеринга

рендер функция

render() {
        const {title, description, tagtext, siteName} = (this.state.selected !== undefined) ? this.state.selected : {};
        const hasContentChangedYet = this.hasContentChangedYet(title, description);

        return (
            <div>
                <h2 className={styles.formMainHeader}>Edit Meta-Data Form</h2>
                <table className={styles.formBlock}>
                    <tbody>
                    <tr>
                        <td className={styles.tagEditLabel}>
                            Tag
                        </td>
                        <td className={styles.inputFieldDisableContainer}>
                            {tagtext}
                        </td>
                    </tr>
                    <tr>
                        <td className={styles.tagEditLabel}>
                            Site
                        </td>
                        <td className={styles.inputFieldDisableContainer}>
                            {siteName}
                        </td>
                    </tr>
                    <tr>
                        <td className={styles.tagEditLabel}>
                            Title
                        </td>
                        <td className={styles.inputFieldContainer}>
                            <ReactInputField
                                ref="titleInput"
                                id="title"
                                defaultValue={(title) ? title : ''}
                                onChange={this.onInputChange}
                                placeholder="Title"
                                clearTool={true} />
                        </td>
                    </tr>
                    <tr>
                        <td className={styles.tagEditLabel}>
                            Description
                        </td>
                        <td className={styles.inputFieldContainer}>
                            <ReactInputField
                                id="description"
                                defaultValue={(description) ? description : ''}
                                onChange={this.onInputChange}
                                placeholder="Description"
                                clearTool={true} />
                        </td>
                    </tr>
                    </tbody>
                </table>

                <div className={styles.formFooter}>
                    <button id="save-button" className={styles.saveButton} disabled={!hasContentChangedYet} onClick={() => this.handleSavePressed()}>
                        Save
                    </button>
                    <button id="form-cancel-button" className={styles.cancelButton} onClick={this.actions.form.cancelUpdateToTagData}>
                        Cancel
                    </button>

                </div>
            </div>
        );
    }

1 ответов


увидев обновление вопроса, я понимаю, что у вас глубоко вложенный HTML передан оказать функция, и входной элемент вашего интереса действительно не будет доступен во время componentDidMount вызов элемента предка. Как указано в реагировать v0.13 Изменить Журнал:

ref порядок разрешения немного изменился, так что ссылка на компонент доступна сразу после его componentDidMount вызывается метод; это изменение должно наблюдаться только в том случае, если ваш компонент вызывает обратный вызов родительского компонента в вашем componentDidMount, который является анти-шаблон и следует избегать независимо

это ваше дело. Таким образом, либо вы должны разбить структуру HTML на отдельно отображаемые элементы, как описано здесь, а затем вы получите доступ к элементу ввода в своем собственном componentDidMount обратный вызов; или вы просто придерживаетесь таймер взломать у вас есть.

использование componentDidMount гарантирует, что код выполняется только тогда, когда компонент на котором он называется is установлен (см. цитату из документов ниже).

обратите внимание, что вызов реагировать.findDOMNode не рекомендуется:

в большинстве случаев вы можете прикрепить ссылку к узлу DOM и избежать использования findDOMNode на всех.

Примечание

findDOMNode() люк используется для доступа к базовому узлу DOM. В большинстве случаев использование этого аварийного люка не рекомендуется, поскольку он проникает в абстракцию компонентов.

findDOMNode() работает только на монтируемых компонентах (то есть компонентах, которые были помещены в DOM). Если вы попытаетесь вызвать это на компоненте, который еще не был смонтирован (например, вызов findDOMNode() на render() на компоненте, который еще должен быть создать) будет выдано исключение.

и из документов на ref string attribute:

  1. присвоить ref атрибут для всего, что возвращается из render, например:

     <input ref="myInput" />
    
  2. в некотором другом коде (обычно код обработчика событий), доступ к резервное копирование экземпляра via this.refs в:

    var input = this.refs.myInput;  
    var inputValue = input.value;  
    var inputRect = input.getBoundingClientRect();  
    

кроме того, вы можете устранить необходимость кода и использовать JSX :

<ReactInputField
        ref="titleInput"
        autoFocus
        ... />