Фокусировка элементов div с помощью React
Можно ли сфокусировать div (или любые другие элементы) с помощью метода focus()
?
Я установил tabIndex в элемент div:
<div ref="dropdown" tabIndex="1"></div>
И я вижу, что он фокусируется, когда я нажимаю на него, однако я пытаюсь динамически сфокусировать элемент следующим образом:
setActive(state) {
ReactDOM.findDOMNode(this.refs.dropdown).focus();
}
Или вот так:
this.refs.dropdown.focus();
Но компонент не получает фокус при срабатывании события. Как я могу это сделать? Есть ли какой-нибудь другой (не входной) элемент, который я могу использовать для этого?
EDIT:
Ну, похоже, это действительно можно сделать: https://jsfiddle.net/69z2wepo/54201/
Но это не работает для меня, это мой полный код:
class ColorPicker extends React.Component {
constructor(props) {
super(props);
this.state = {
active: false,
value: ""
};
}
selectItem(color) {
this.setState({ value: color, active: false });
}
setActive(state) {
this.setState({ active: state });
this.refs.dropdown.focus();
}
render() {
const { colors, styles, inputName } = this.props;
const pickerClasses = classNames('colorpicker-dropdown', { 'active': this.state.active });
const colorFields = colors.map((color, index) => {
const colorClasses = classNames('colorpicker-item', [`colorpicker-item-${color}`]);
return (
<div onClick={() => { this.selectItem(color) }} key={index} className="colorpicker-item-container">
<div className={colorClasses}></div>
</div>
);
});
return (
<div className="colorpicker">
<input type="text" className={styles} name={inputName} ref="component" value={this.state.value} onFocus={() => { this.setActive(true) }} />
<div onBlur={() => this.setActive(false) } onFocus={() => console.log('focus')} tabIndex="1" ref="dropdown" className={pickerClasses}>
{colorFields}
</div>
</div>
);
}
}
Ответы
Ответ 1
Реакция перерисовывает компонент каждый раз, когда вы устанавливаете состояние, что означает, что компонент теряет фокус. В подобных случаях удобно использовать методы componentDidUpdate
или componentDidMount
, если вы хотите сфокусировать элемент на основе элемента prop или state.
Имейте в виду, что в соответствии с документацией React Lifecycle componentDidMount
произойдет только после визуализации компонента в первый раз на экране, а в этом вызове componentDidUpdate
не произойдет, то для каждого нового setState
forceUpdate
или компонент, получающий новые реквизиты, вызовет вызов componentDidUpdate
.
componentDidMount() {
this.focusDiv();
},
componentDidUpdate() {
if(this.state.active)
this.focusDiv();
},
focusDiv() {
ReactDOM.findDOMNode(this.refs.theDiv).focus();
}
Вот скрипт JS, с которым вы можете играть.
Ответ 2
В этом проблема:
this.setState({ active: state });
this.refs.component.focus();
Заданное состояние перезаписывает ваш компонент, а вызов является асинхронным, поэтому вы фокусируетесь, он сразу же восстанавливается после того, как он фокусируется, и вы теряете фокус. Попробуйте использовать обратный вызов setState
this.setState({ active: state }, () => {
this.refs.component.focus();
});
Ответ 3
Немного поздно, чтобы ответить, но причина, по которой ваш обработчик событий не работает, возможно, в том, что вы не привязываете свои функции, и поэтому "this", используемое внутри функции, будет неопределенным, если вы передадите его, например: "this.selectItem(color) "
В конструкторе делаем:
this.selectItem = this.selectItem.bind(this)
this.setActive = this.setActive.bind(this)
Ответ 4
import React from "react"
import ReactDOM from 'react-dom';
export default class DivFocusReactJs extends React.Component {
constructor(props) {
super(props)
this.state = {
}
}
componentDidMount() {
ReactDOM.findDOMNode(this.refs.divFocus).focus();
}
render() {
return (
<div tabIndex={1} ref="divFocus">
<p>Focusing div elements with React</p>
{/*your code here...*/}
</div>
)
}
}
Ответ 5
Это работало в моем случае
render: function(){
if(this.props.edit){
setTimeout(()=>{ this.divElement.focus() },0)
}
return <div ref={ divElement => this.divElement = divElement}
contentEditable={props.edit}/>
}
Ответ 6
Не уверен, что это правильный путь, но я обнаружил, что это работает для меня.
render() {
return <div ref='item' onLoad={() => this.refs.item.focus()}>I will have focus</div>
}