Установка фокуса на ввод после рендеринга
каков способ react установки фокуса на определенном текстовом поле после визуализации компонента?
документация, кажется, предлагает использовать ссылки, например:
Set ref="nameInput" в моем поле ввода в функции рендеринга, а затем вызовите:
this.refs.nameInput.getInputDOMNode().focus();
но где я должен это назвать? Я пробовал несколько мест, но я не могу заставить его работать.
19 ответов:
вы должны сделать его в
componentDidMountиrefs callbackвместо. Что-то вроде этогоcomponentDidMount(){ this.nameInput.focus(); }class App extends React.Component{ componentDidMount(){ this.nameInput.focus(); } render() { return( <div> <input defaultValue="Won't focus" /> <input ref={(input) => { this.nameInput = input; }} defaultValue="will focus" /> </div> ); } } ReactDOM.render(<App />, document.getElementById('app'));<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.js"></script> <div id="app"></div>
@Dhiraj ответ правильный, и для удобства вы можете использовать автофокус prop, чтобы иметь вход автоматически фокусироваться при монтаже:
<input autoFocus name=...обратите внимание, что в jsx это
autoFocus(capital F) в отличие от обычного старого html, который не учитывает регистр.
Если вы просто хотите сделать автофокус в React, это просто.
<input autoFocus type="text" />
а если вы просто хотите знать, куда поместить этот код, ответ в componentDidMount().
v014.3
componentDidMount() { this.refs.linkInput.focus() }в большинстве случаев вы можете прикрепить ссылку к узлу DOM и вообще не использовать findDOMNode.
прочитайте документы API здесь: https://facebook.github.io/react/docs/top-level-api.html#reactdom.finddomnode
я просто столкнулся с этой проблемой, и я использую react
15.0.115.0.2 и я использую синтаксис ES6 и не совсем получил то, что мне нужно от других ответов, так как v. 15 упал несколько недель назад и некоторые изthis.refsсвойства были устаревшими и удалены.в общем, то, что мне нужно было:
- сфокусируйте первый элемент ввода (поля), когда компонент монтируется
- сфокусировать первый вход (поле) элемент с ошибкой (после отправки)
я:
- React Container / Presentation Component
- возвращение
- React-Router
сфокусируйте первый элемент ввода
я
autoFocus={true}первый<input />на странице, так что когда компонент монтируется, он получит фокус.сфокусируйте первый элемент ввода с ошибкой
это заняло больше времени и было больше извилистый. Я держу код, который не имеет отношения к решению для краткости.
Redux Store / State
мне нужно глобальное состояние, чтобы знать, должен ли я установить фокус и отключить его, когда он был установлен, поэтому я не продолжаю переустанавливать фокус, когда компоненты перерисовываются (я буду использовать
componentDidUpdate()для проверки установки фокуса.)это может быть спроектировано так, как вы считаете нужным для вашего приложения.
{ form: { resetFocus: false, } }Контейнер Компонент
в компонент должен будет иметь
resetfocusнабор свойств и обратный вызов, чтобы очистить свойство, если оно заканчивается установкой фокуса на себя.Также обратите внимание, что я организовал своих создателей действий в отдельные файлы в основном из-за того, что мой проект довольно большой, и я хотел разбить их на более управляемые куски.
import { connect } from 'react-redux'; import MyField from '../presentation/MyField'; import ActionCreator from '../actions/action-creators'; function mapStateToProps(state) { return { resetFocus: state.form.resetFocus } } function mapDispatchToProps(dispatch) { return { clearResetFocus() { dispatch(ActionCreator.clearResetFocus()); } } } export default connect(mapStateToProps, mapDispatchToProps)(MyField);Презентация Компонента
import React, { PropTypes } form 'react'; export default class MyField extends React.Component { // don't forget to .bind(this) constructor(props) { super(props); this._handleRef = this._handleRef.bind(this); } // This is not called on the initial render so // this._input will be set before this get called componentDidUpdate() { if(!this.props.resetFocus) { return false; } if(this.shouldfocus()) { this._input.focus(); this.props.clearResetFocus(); } } // When the component mounts, it will save a // reference to itself as _input, which we'll // be able to call in subsequent componentDidUpdate() // calls if we need to set focus. _handleRef(c) { this._input = c; } // Whatever logic you need to determine if this // component should get focus shouldFocus() { // ... } // pass the _handleRef callback so we can access // a reference of this element in other component methods render() { return ( <input ref={this._handleRef} type="text" /> ); } } Myfield.propTypes = { clearResetFocus: PropTypes.func, resetFocus: PropTypes.bool }обзор
общая идея заключается в том, что каждое поле формы, которое может иметь ошибку и быть focused должен проверить себя, и если ему нужно установить фокус на себя.
есть бизнес-логика, которая должна произойти, чтобы определить, является ли данное поле правильным полем для установки фокуса. Это не показано, потому что это будет зависеть от отдельного приложения.
при отправке формы это событие должно установить флаг глобального фокуса
resetFocusзначение true. Затем, когда каждый компонент обновляет себя, он увидит, что он должен проверить, получает ли он фокус, и если да, отправьте событие для сброса фокуса, чтобы другим элементам не нужно было продолжать проверку.edit В качестве примечания, у меня была моя бизнес-логика в файле "утилиты", и я просто экспортировал метод и вызвал его в каждом
shouldfocus()метод.Ура!
в документах React теперь есть раздел для этого. https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute
render: function() { return ( <TextInput ref={function(input) { if (input != null) { input.focus(); } }} /> ); },
Ref. Комментарий @Dave к ответу @Dhiraj; альтернативой является использование функции обратного вызова атрибута ref для отображаемого элемента (после первого отображения компонента):
<input ref={ function(component){ React.findDOMNode(component).focus();} } />
это правильный способ, как автофокус. При использовании обратного вызова вместо строки в качестве значения ref, он вызывается автоматически. Вы получили свой ref доступен, чем без необходимости прикасаться к DOM с помощью
getDOMNoderender: function() { return <TextInput ref={(c) => this._input = c} />; }, componentDidMount: function() { this._input.focus(); },
это уже не лучший ответ. По состоянию на v0. 13,
this.refsможет быть недоступно доcomponentDidMount()работает, в некоторых нечетных случаях.просто добавить
autoFocusтег в поле ввода, как FakeRainBrigand показано выше.
вы можете поместить этот вызов метода внутри функции рендеринга. Или внутри метода жизненного цикла,
componentDidUpdate
обратите внимание, что ни один из этих ответов работал для меня материал-компонент текстового поля ui. Пер Как установить фокус на текстовое поле materialUI? мне пришлось прыгать через некоторые обручи, чтобы заставить это работать:
const focusUsernameInputField = input => { if (input) { setTimeout(() => {input.focus()}, 100); } }; return ( <TextField hintText="Username" floatingLabelText="Username" ref={focusUsernameInputField} /> );
не нужно
getInputDOMNode?? в этом деле...просто взять
refиfocus()это когда компонент монтируется -- componentDidMount...import React from 'react'; import { render } from 'react-dom'; class myApp extends React.Component { componentDidMount() { this.nameInput.focus(); } render() { return( <div> <input ref={input => { this.nameInput = input; }} /> </div> ); } } ReactDOM.render(<myApp />, document.getElementById('root'));
автофокус работал лучше для меня. Мне нужно было изменить какой-то текст на вход с этим текстом на двойной щелчок, так что это то, что я закончил с:
<input autoFocus onFocus={this.setCaretToEnd} value={this.state.editTodo.value} onDoubleClick={this.updateTodoItem} />Примечание: чтобы устранить проблему, когда React помещает курсор в начале текста, используйте этот метод:
setCaretToEnd(event) { var originalText = event.target.value; event.target.value = ''; event.target.value = originalText; }найти здесь: https://coderwall.com/p/0iz_zq/how-to-put-focus-at-the-end-of-an-input-with-react-js
предупреждение: ReactDOMComponent: не получить доступ .getDOMNode () узла DOM; вместо этого используйте узел напрямую. Этот узел DOM был визуализирован
App.должно быть
componentDidMount: function () { this.refs.nameInput.focus(); }
самый простой ответ-добавить ref= "некоторое имя" во входной текстовый элемент и вызвать функцию ниже.
componentDidMount(){ this.refs.field_name.focus(); } // here field_name is ref name. <input type="text" ref="field_name" />
У меня такая же проблема, но у меня тоже есть анимация, поэтому мой коллега предлагает использовать окно.requestAnimationFrame
это ref атрибут моего элемента:
ref={(input) => {input && window.requestAnimationFrame(()=>{input.focus()})}}
прочитал почти весь ответ, но не увидел
getRenderedComponent().props.inputустановите ссылки для ввода текста
this.refs.username.getRenderedComponent().props.input.onChange('');
после попытки много вариантов выше без успеха я обнаружил, что это было, как я был
disablingа тоenablingвход, который вызвал потерю фокуса.у меня был проп
sendingAnswerкоторый отключил бы вход, пока я опрашивал бэкэнд.<Input autoFocus={question} placeholder={ gettingQuestion ? 'Loading...' : 'Type your answer here...' } value={answer} onChange={event => dispatch(updateAnswer(event.target.value))} type="text" autocomplete="off" name="answer" // disabled={sendingAnswer} <-- Causing focus to be lost. />как только я удалил отключенную опору, все снова начало работать.
обновленную версию вы можете проверить здесь
componentDidMount() { // Focus to the input as html5 autofocus this.inputRef.focus(); } render() { return <input type="text" ref={(input) => { this.inputRef = input }} /> })
Comments