Javascript 使用 React 聚焦 div 元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39174887/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 22:18:16  来源:igfitidea点击:

Focusing div elements with React

javascriptreactjs

提问by Carlos Martinez

Is it possible to focus div (or any other elements) using the focus()method?

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

I've set a tabIndex to a div element:

我已将 tabIndex 设置为 div 元素:

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

And I can see it gets focused when I click on it, however, I'm trying to dynamically focus the element like this:

当我点击它时,我可以看到它被聚焦,但是,我试图像这样动态聚焦元素:

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

Or like this:

或者像这样:

this.refs.dropdown.focus();

But the component doesn't get focus when the event is triggered. How can I do this? Is there any other (not input) element I can use for this?

但是当事件被触发时组件没有获得焦点。我怎样才能做到这一点?是否有任何其他(非输入)元素可以用于此目的?

EDIT:

编辑:

Well, It seems this it actually possible to do: https://jsfiddle.net/69z2wepo/54201/

好吧,这似乎实际上可以做到:https: //jsfiddle.net/69z2wepo/54201/

But it is not working for me, this is my full code:

但这对我不起作用,这是我的完整代码:

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>
    );
  }
}

回答by vankov.ilija

React redraws the component every time you set the state, meaning that the component loses focus. In this kind of instances it is convenient to use the componentDidUpdateor componentDidMountmethods if you want to focus the element based on a prop, or state element.

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

Keep in mind that as per React Lifecycle documentation, componentDidMountwill only happen after rendering the component for the first time on the screen, and in this call componentDidUpdatewill not occur, then for each new setState, forceUpdatecall or the component receiving new props the componentDidUpdatecall will occur.

请记住,根据 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();
}

Here is a JS fiddleyou can play around with.

这是您可以玩的JS 小提琴

回答by Rob M.

This is the problem:

这就是问题:

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

Set state is rerendering your component and the call is asynchronous, so you arefocusing, it's just immediately rerendering after it focuses and you lose focus. Try using the setStatecallback

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

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

回答by Hamza Khan

A little late to answer but the reason why your event handler is not working is probably because you are not binding your functions and so 'this' used inside the function would be undefined when you pass it as eg: "this.selectItem(color)"

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

In the constructor do:

在构造函数中:

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

this.setActive = this.setActive.bind(this)

回答by jayesh desai

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>
    )
  }
}

回答by ASmater.Me

This worked in my case

这在我的情况下有效

render: function(){

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

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

回答by Kevin

Not sure if this is the proper way, but I found that this worked for me.

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

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