问题 用React聚焦div元素


是否可以使用the来聚焦div(或任何其他元素) focus() 方法?

我已经将tabIndex设置为div元素:

<div ref="dropdown" tabIndex="1"></div>

当我点击它时,我可以看到它变得集中,但是,我正在尝试动态聚焦这样的元素:

setActive(state) {
  ReactDOM.findDOMNode(this.refs.dropdown).focus();
}

或者像这样:

this.refs.dropdown.focus();

但是,当触发事件时,组件不会获得焦点。我怎样才能做到这一点?我可以使用其他(非输入)元素吗?

编辑:

嗯,这似乎有可能做到: 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>
    );
  }
}

4784
2017-08-26 21:31


起源

你在哪里指定参考? - Matthew Herbst
抱歉,更新了,我正在使用tabIndex将ref分配给相同的div元素 - Carlos Martinez
我在小提琴中尝试了这个并且它有效 jsfiddle.net/69z2wepo/54201,但没有在我的代码中工作,我更新问题包括它 - Carlos Martinez


答案:


每次设置状态时,React都会重新绘制组件,这意味着组件失去焦点。在这种情况下,使用它很方便 componentDidUpdate 要么 componentDidMount 方法,如果要基于prop或state元素聚焦元素。

请记住,根据React Lifecycle文档, componentDidMount 只有在屏幕上和此调用中第一次渲染组件后才会发生 componentDidUpdate 不会发生,然后为每个新的 setStateforceUpdate 呼叫或接收新道具的组件 componentDidUpdate 电话会发生。

componentDidMount() {
  this.focusDiv();
},
componentDidUpdate() {
  if(this.state.active)
    this.focusDiv();
},
focusDiv() {
  ReactDOM.findDOMNode(this.refs.theDiv).focus();
}

这里有一个 JS小提琴 你可以玩。


14
2017-08-26 23:14



这很有意思,谢谢你! componentDidUpdate 做了伎俩 - Carlos Martinez


这就是问题:

this.setState({ active: state });
this.refs.component.focus();

设置状态正在重新呈现您的组件,并且调用是异步的,所以您  聚焦,它只是在它聚焦后立即重新渲染并且你失去焦点。尝试使用 setState 回电话

this.setState({ active: state }, () => {
   this.refs.component.focus();
});

2
2017-08-26 23:01



嗯,不,即使我不调用setState元素没有得到焦点:( - Carlos Martinez


这适用于我的情况

render: function(){

  if(this.props.edit){
    setTimeout(()=>{ this.divElement.focus() },0)
  }

    return <div ref={ divElement => this.divElement = divElement}
                contentEditable={props.edit}/>
}

-1
2017-09-27 10:54





不确定这是否正确,但我发现这对我有用。

render() {
  return <div ref='item' onLoad={() => this.refs.item.focus()}>I will have focus</div>
}

-1
2018-05-07 06:10