簡體   English   中英

React,如何從同一個組件訪問我的渲染函數中的 DOM 元素

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

我想知道從同一組件訪問渲染函數中的 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>
        )



})

您可以使用ReactDOM.findDOMNode(this)來訪問底層DOM節點。 但訪問DOM節點並像操作一樣操作是違反React編程風格的。 最好使用狀態變量並調用setState方法來重新呈現DOM。

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

您可以使用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

這是我的解決方案:要獲取特定元素的computedCss,您需要首先向elemenet添加ref屬性。

在此輸入圖像描述

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

然后,在componentDidUpdate()函數中,使用window.getComputedStyle(this.refs.lineChartWrap)獲取元素的css .XXX 在此處輸入圖像描述

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

你應該避免訪問DOM元素,因為反應的重點是將抽象放在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中,當您的組件被掛載時,將應用其樣式更改。

剛剛在使用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 Elements沒有明確地等於React Components。 如果您需要以任何方式操縱DOM,請先以反應方式進行操作。 這是一個邊緣情況,我寧願依靠動態表單的表單驗證,而不是手動執行非常繁重的自定義驗證。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM