Javascript React,如何从同一个组件访问我的渲染函数中的 DOM 元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42242146/
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 01:00:19  来源:igfitidea点击:

React, how to access the DOM element in my render function from the same component

javascriptcssreactjsjsx

提问by wonghenry

I'm wondering what's the best practice for accessing the DOM elements inside my render function from the same component. Note that I will be rendering this component multiple times on a page.

我想知道从同一组件访问渲染函数中的 DOM 元素的最佳实践是什么。请注意,我将在页面上多次渲染此组件。

e.g.

例如

var TodoItem = React.createClass({
    ...
    render:function(){

        function oneSecLater(){
            setTimeout(function(){
            //select the current className? this doesn't work, but it gives you an idea what I want.
            document.getElementsByClassName('name').style.backgroundColor = "red";
                )}, 1000);
        }

        return(
            <div className='name'>{this.oneSecLater}</div>
        )



})

采纳答案by Saba Hassan

Here, no need to use setTimeout. There are lifecycle methods for component, of which componentDidMountis called after the render. So, you can get the reference to your div in the method.

在这里,不需要使用 setTimeout。组件有生命周期方法,componentDidMount在渲染后调用。因此,您可以在方法中获取对 div 的引用。

var TodoItem = React.createClass({
  ...
  componentDidMount: function () {
     if(this.myDiv) {
        this.myDiv.style.backgroundColor = "red";
     }
  }
  render:function(){
    return(
        <div className='name' ref = {c => this.myDiv = c}></div>
    );
});

回答by VJAI

You can use ReactDOM.findDOMNode(this)to access the underlying DOM node. But accessing the DOM node and manipulating like you do is against the React style of programming. It's better to use a state variable and called the setStatemethod to re-render the DOM.

您可以使用ReactDOM.findDOMNode(this)来访问底层 DOM 节点。但是访问 DOM 节点并像您一样操作是违反 React 编程风格的。最好使用状态变量并调用setState方法重新渲染DOM。

回答by Shubham Khatri

You can make use of ref callbackto access the dom element in react, which is what React Docs recommend to follow

你可以使用ref callback访问 react 中的 dom 元素,这是 React Docs 推荐遵循的

and do that in the componentDidMountlifecycle function as refs won't be accessible before the DOM is created

并在componentDidMount生命周期函数中执行此操作,因为在创建 DOM 之前将无法访问 refs

var TodoItem = React.createClass({
    ...
    componentDidMount() {
          setTimeout(function(){
               this.myDiv.style.backgroundColor = "red";
          )}, 1000);
    }
    render:function(){

        return(
            <div className='name' ref={(ele) => this.myDiv = ele}></div>
        )

})

DOCS

文档

回答by Yilmaz

You should avoid accessing DOM element because the whole point of react is putting abstraction over dom. React keeps representation of DOM in memory which is referred as VirtualDom. Working with VirtualDom will make unit testing your application is easier.If you really know what you are doing, here is how to do it:

您应该避免访问 DOM 元素,因为 React 的全部意义在于将抽象置于 dom 之上。React 将 DOM 的表示保留在内存中,称为 VirtualDom。使用 VirtualDom 将使您的应用程序的单元测试更容易。如果您真的知道自己在做什么,下面是如何做:

componentDidMount(){
const name=this.name.current.style() //current will return the actual DOM 
element
}
name=React.createRef()  //create a ref object

<div ref={this.name} className="anything" /> //your classname does not need to be named as "name". You access the element via the "ref" attribute not the classname.

In ComponentDidMount, when your component is mounted its style change will be applied.

在 ComponentDidMount 中,当您的组件被挂载时,其样式更改将被应用。

回答by Dark Swordsman

Just came across this after trying to do form validation before opening a stripe checkout modal with React 14.

在使用 React 14 打开条带结帐模式之前尝试进行表单验证后刚刚遇到了这个问题。

I would like to note that you're not actually accessing a DOM Element with references. You're simply accessing the React Component Object. Shown here:

我想指出的是,您实际上并没有通过引用访问 DOM 元素。您只是访问 React 组件对象。显示在这里:

enter image description here

在此处输入图片说明

The top one is calling ref.ticketForm, the bottom is showing document.getElementById('ticketform').

上面一个叫ref.ticketForm,下面一个显示document.getElementById('ticketform')

The reason I needed to do this was the following:

我需要这样做的原因如下:

<Button color="success" size="lg" type="button" onClick={(e) => {
  const ticketForm = document.getElementById('ticketForm');
  const isValid = ticketForm.reportValidity();
  if (!isValid) e.stopPropagation();
}}>Buy Tickets</Button>

reportValidity()is a DOM Element method: https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/reportValidity

reportValidity()是一个 DOM 元素方法:https: //developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/reportValidity

Referencing this issue, this person showed this method being used on a reference object, which naturally isn't correct: https://github.com/azmenak/react-stripe-checkout/issues/121#issuecomment-431635855

引用这个issue,这个人把这个方法用在一个引用对象上,自然是不对的:https: //github.com/azmenak/react-stripe-checkout/issues/121#issuecomment-431635855

Hopefully this clears up that DOM Elements do not explicitly equal React Components. If you need to manipulate the DOM in any way, do it in a react way first. This is an edge case where I would rather rely on form validation for a dynamic form than manually doing very heavy custom validation.

希望这可以澄清 DOM 元素并不明确等于 React 组件。如果您需要以任何方式操作 DOM,请先以反应方式进行操作。这是一个边缘情况,我宁愿依赖动态表单的表单验证而不是手动进行非常繁重的自定义验证。

回答by juana pu

here is my solution: To get a computedCss of an specific element, you need to add a ref attribute to the elemenet first.

这是我的解决方案:要获取特定元素的计算 Css,您需要先向 elemenet 添加 ref 属性。

enter image description here

在此处输入图片说明

render(){
  <div>
    <Row className="chartline2">
      <Col className="gutter-row" span={24}>
        <div className="gutter-box lineChartWrap" id="lineChartWrap" ref="lineChartWrap">
            <LineChart data={lineChartData} options={lineChartOptions} width="100%" height="300"/>
        </div>
      </Col>
    </Row>
  </div>
}

And then, in the componentDidUpdate() function, get your element's css by using window.getComputedStyle(this.refs.lineChartWrap).XXX enter image description here

然后,在 componentDidUpdate() 函数中,使用 window.getComputedStyle(this.refs.lineChartWrap).XXX在此处输入图像描述来获取元素的 css

 componentDidUpdate(){
  console.log("-------  get width ---");
  let ele = document.querySelector("#lineCharWrap");
  console.log(this.refs.lineChartWrap);
  console.log(window.getComputedStyle(this.refs.lineChartWrap).width);
 }

回答by Jenya Khrichtchatyi

componentDidMount(){
    document.querySelector("#myElem").innerHTML = "Boom!";
}