javascript - tutorial - react是什麼




反應“渲染後”的代碼? (8)

我有一個應用程序,我需要動態設置元素的高度(可以說“app-content”)。 它需要應用程序的“chrome”的高度並將其減去,然後將“app-content”的高度設置為在這些約束內適合100%。 這對於vanilla JS,jQuery或Backbone視圖來說是非常簡單的,但是我正在努力弄清楚在React中做這件事的正確過程是什麼?

以下是一個示例組件。 我希望能夠將app-content的高度設置為窗口的100%減去ActionBarBalanceBar的大小,但是如何知道何時呈現了所有內容以及將計算內容放入此React類中的位置?

/** @jsx React.DOM */
var List = require('../list');
var ActionBar = require('../action-bar');
var BalanceBar = require('../balance-bar');
var Sidebar = require('../sidebar');
var AppBase = React.createClass({
  render: function () {
    return (
      <div className="wrapper">
        <Sidebar />
        <div className="inner-wrapper">
          <ActionBar title="Title Here" />
          <BalanceBar balance={balance} />
          <div className="app-content">
            <List items={items} />
          </div>
        </div>
      </div>
    );
  }
});

module.exports = AppBase;

React在這些情況下有很少的生命週期方法,包括但不限於getInitialState,getDefaultProps,componentWillMount,componentDidMount等。

在你的情況和需要與DOM元素進行交互的情況下,你需要等到dom準備就緒,所以使用componentDidMount如下:

/** @jsx React.DOM */
var List = require('../list');
var ActionBar = require('../action-bar');
var BalanceBar = require('../balance-bar');
var Sidebar = require('../sidebar');
var AppBase = React.createClass({
  componentDidMount: function() {
    ReactDOM.findDOMNode(this).height = /* whatever HEIGHT */;
  },
  render: function () {
    return (
      <div className="wrapper">
        <Sidebar />
        <div className="inner-wrapper">
          <ActionBar title="Title Here" />
          <BalanceBar balance={balance} />
          <div className="app-content">
            <List items={items} />
          </div>
        </div>
      </div>
    );
  }
});

module.exports = AppBase;

關於反應生命週期的更多信息,你可以看看下面的鏈接: https://facebook.github.io/react/docs/state-and-lifecycle.htmlhttps://facebook.github.io/react/docs/state-and-lifecycle.html


https://facebook.github.io/react/docs/react-component.html#componentdidmount

這個方法在你的組件被渲染後被調用一次。 所以你的代碼看起來像這樣。

var AppBase = React.createClass({
  componentDidMount: function() {
    var $this = $(ReactDOM.findDOMNode(this));
    // set el height and width etc.
  },

  render: function () {
    return (
      <div className="wrapper">
        <Sidebar />
          <div className="inner-wrapper">
            <ActionBar title="Title Here" />
            <BalanceBar balance={balance} />
            <div className="app-content">
              <List items={items} />
          </div>
        </div>
      </div>
    );
  }
});

實際上,我遇到了類似問題,我在Component中使用它的id屬性渲染視頻元素,所以當RenderDOM.render()結束時,它會加載需要id的插件以找到佔位符,並且無法找到它。

componentDidMount()中的0ms的setTimeout修復了它:)

componentDidMount() {
    if (this.props.onDidMount instanceof Function) {
        setTimeout(() => {
            this.props.onDidMount();
        }, 0);
    }
}

對我而言, window.requestAnimationFramesetTimeout組合沒有產生一致的結果。 有時候它有效,但並不總是 - 或者有時候會太遲。

我通過多次循環window.requestAnimationFrame來修復它。
(通常為0或2-3次)

關鍵是diff > 0 :在這裡我們可以確保頁面更新的準確時間。

// Ensure new image was loaded before scrolling
if (oldH > 0 && images.length > prevState.images.length) {
    (function scroll() {
        const newH = ref.scrollHeight;
        const diff = newH - oldH;

        if (diff > 0) {
            const newPos = top + diff;
            window.scrollTo(0, newPos);
        } else {
            window.requestAnimationFrame(scroll);
        }
    }());
}

我覺得這個解決方案很骯髒,但是這裡我們去了:

componentDidMount() {
    this.componentDidUpdate()
}

componentDidUpdate() {
    // A whole lotta functions here, fired after every render.
}

現在我正要坐在這裡等待倒票。


我遇到了同樣的問題。

componentDidMount()中使用hack-ish setTimeout(() => { }, 0)大多數情況下工作。

但不是在特殊情況下; 我不想使用ReachDOM findDOMNode因為文檔說:

注意:findDOMNode是用於訪問底層DOM節點的轉義影線。 在大多數情況下,不鼓勵使用這個逃生艙口,因為它穿透了組件抽象。

(來源: https://facebook.github.io/react/docs/react-dom.html#finddomnodehttps://facebook.github.io/react/docs/react-dom.html#finddomnode

所以在那個特定的組件中,我不得不使用componentDidUpdate()事件,所以我的代碼就像這樣:

componentDidMount() {
    // feel this a little hacky? check this: http://.com/questions/26556436/react-after-render-code
    setTimeout(() => {
       window.addEventListener("resize", this.updateDimensions.bind(this));
       this.updateDimensions();
    }, 0);
}

接著:

componentDidUpdate() {
    this.updateDimensions();
}

最後,就我而言,我不得不移除在componentDidMount創建的監聽器:

componentWillUnmount() {
    window.removeEventListener("resize", this.updateDimensions.bind(this));
}

渲染之後,您可以指定如下所示的高度,並可以指定相應反應組件的高度。

render: function () {
    var style1 = {height: '100px'};
    var style2 = { height: '100px'};

   //window. height actually will get the height of the window.
   var hght = $(window).height();
   var style3 = {hght - (style1 + style2)} ;

    return (
      <div className="wrapper">
        <Sidebar />
        <div className="inner-wrapper">
          <ActionBar style={style1} title="Title Here" />
          <BalanceBar style={style2} balance={balance} />
          <div className="app-content" style={style3}>
            <List items={items} />
          </div>
        </div>
      </div>
    );`
  }

或者您可以使用sass指定每個反應組件的高度。 用固定寬度指定前2個反應組分主div,然後用自動指定第三個組分主div的高度。 所以根據第三個div的內容分配高度。


ES6類而不是React.createClass進行一些更新

import React, { Component } from 'react';

class SomeComponent extends Component {
  constructor(props) {
    super(props);
    // this code might be called when there is no element avaliable in `document` yet (eg. initial render)
  }

  componentDidMount() {
    // this code will be always called when component is mounted in browser DOM ('after render')
  }

  render() {
    return (
      <div className="component">
        Some Content
      </div>
    );
  }
}

另外 - 檢查React組件生命週期方法: https://facebook.github.io/react/docs/react-component.html#the-component-lifecyclehttps://facebook.github.io/react/docs/react-component.html#the-component-lifecycle

每個組件都有許多類似於componentDidMount的方法,例如。

  • componentWillUnmount() - 組件即將從瀏覽器DOM中刪除






reactjs