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

Posted

技术标签:

【中文标题】React,如何从同一个组件访问我的渲染函数中的 DOM 元素【英文标题】:React, how to access the DOM element in my render function from the same component 【发布时间】:2017-07-03 16:29:12 【问题描述】:

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

例如

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



)

【问题讨论】:

【参考方案1】:

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

【讨论】:

谨慎使用,因为文档现在说“findDOMNode 是用于访问底层 DOM 节点的逃生舱口。在大多数情况下,不鼓励使用此逃生舱口,因为它会穿透组件抽象. 它已在 StrictMode 中被弃用。" 这在严格模式下已被弃用。【参考方案2】:

这里,不需要使用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>
    );
);

【讨论】:

似乎在最新版本的 React 中,他们建议使用 React.createRef() 而不是回调 api。 reactjs.org/docs/refs-and-the-dom.html#creating-refs【参考方案3】:

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

并在 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

【讨论】:

【参考方案4】:

您应该避免访问 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.

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

【讨论】:

【参考方案5】:

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

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

上面是调用ref.ticketForm,下面是document.getElementById('ticketform')

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

<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() 是一个 DOM 元素方法:https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/reportValidity

引用这个问题,这个人展示了这个方法被用于一个引用对象,这自然是不正确的:https://github.com/azmenak/react-stripe-checkout/issues/121#issuecomment-431635855

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

【讨论】:

【参考方案6】:

这是我的解决方案: 要获取特定元素的 computedCss,您需要先向 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  />
        </div>
      </Col>
    </Row>
  </div>

然后,在 componentDidUpdate() 函数中,使用 window.getComputedStyle(this.refs.lineChartWrap).XXX 获取元素的 css enter image description here

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

【讨论】:

以上是关于React,如何从同一个组件访问我的渲染函数中的 DOM 元素的主要内容,如果未能解决你的问题,请参考以下文章

如何从函数调用中渲染 React 子组件?

如何在 REACT 中访问更复杂的嵌套数据 JSON

从 React.js 中的另一个类组件调用函数

react js中如何知道组件渲染情况

react-data-components 渲染组件(按钮),但无法访问在渲染方法之外定义的状态或函数

如何访问react组件中的url参数