使用 React 聚焦 div 元素

IT技术 javascript reactjs
2021-04-22 02:27:10

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

我已将 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>
    );
  }
}
6个回答

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

请记住,根据 React Lifecycle 文档,componentDidMount只有在第一次在屏幕上渲染组件后才会发生,并且在此调用中componentDidUpdate不会发生,然后对于每个 new setStateforceUpdate调用或接收新 props 的组件componentDidUpdate都会发生调用。

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

这是您可以玩JS 小提琴

是否有可能在 5 年后更新 JS 小提琴(任何人)?这只是这个问题的最佳答案,如果有工作示例就好了。我确实尝试过自己,但我想我还不够熟练,谢谢
2021-06-08 02:27:10
这很有趣,谢谢大佬!componentDidUpdate成功了
2021-06-17 02:27:10

这就是问题:

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

设置状态正在重新渲染您的组件并且调用是异步的,因此您正在聚焦,它只是在聚焦后立即重新渲染而您失去焦点。尝试使用setState回调

this.setState({ active: state }, () => {
   this.refs.component.focus();
});
嗯,不,即使我不调用 setState 元素也没有获得焦点:(
2021-06-05 02:27:10

回答有点晚了,但您的事件处理程序不起作用的原因可能是因为您没有绑定您的函数,因此当您将其作为例如“this.selectItem(color)”传递时,函数内部使用的“this”将是未定义的”

在构造函数中:

this.selectItem = this.selectItem.bind(this)

this.setActive = this.setActive.bind(this)
请注意,我使用箭头函数包装了 setActive 函数调用:onFocus={() => { this.setActive(true) }},这样做可以为您提供正确的上下文,因此使用.bind(this)不会改变代码段的工作方式
2021-06-20 02:27:10

这在我的情况下有效

render: function(){

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

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

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

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