本文翻译自:React “after render” code?
I have an app where I need to set the height of an element (lets say "app-content") dynamically. 我有一个应用程序,需要动态设置元素的高度(让我们说“ app-content”)。 It takes the height of the "chrome" of the app and subtracts it and then sets the height of the "app-content" to fit 100% within those constraints. 它获取应用程序“ chrome”的高度,然后减去它的高度,然后将“ app-content”的高度设置为在这些限制内适合100%。 This is super simple with vanilla JS, jQuery, or Backbone views, but I'm struggling to figure out what the right process would be for doing this in React? 这对于香草JS,jQuery或Backbone视图来说非常简单,但我正在努力弄清楚在React中执行此操作的正确过程是什么?
Below is an example component. 下面是一个示例组件。 I want to be able to set app-content
's height to be 100% of the window minus the size of the ActionBar
and BalanceBar
, but how do I know when everything is rendered and where would I put the calculation stuff in this React Class? 我希望能够将app-content
的高度设置为窗口的100%减去ActionBar
和BalanceBar
的大小,但是我怎么知道什么时候呈现所有内容以及将计算内容放在此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 (
);
}
});
module.exports = AppBase;
参考:https://stackoom.com/question/1nQXc/反应-渲染后-代码
componentDidMount() componentDidMount()
This method is called once after your component is rendered. 渲染组件后,将调用此方法一次。 So your code would look like so. 因此您的代码看起来像这样。
var AppBase = React.createClass({
componentDidMount: function() {
var $this = $(ReactDOM.findDOMNode(this));
// set el height and width etc.
},
render: function () {
return (
);
}
});
One drawback of using componentDidUpdate
, or componentDidMount
is that they are actually executed before the dom elements are done being drawn, but after they've been passed from React to the browser's DOM. 使用componentDidUpdate
或componentDidMount
一个缺点是,它们实际上是在绘制完dom元素之前,而是在将它们从React传递到浏览器的DOM之后执行的。
Say for example if you needed set node.scrollHeight to the rendered node.scrollTop, then React's DOM elements may not be enough. 举例来说,如果您需要将node.scrollHeight设置为渲染的node.scrollTop,那么React的DOM元素可能还不够。 You need to wait until the elements are done being painted to get their height. 您需要等到元素完成绘制后才能获得其高度。
Solution: 解:
Use requestAnimationFrame
to ensure that your code is run after the painting of your newly rendered object 使用requestAnimationFrame
确保在绘制新渲染的对象后运行代码
scrollElement: function() {
//store a this ref, and
var _this = this;
//wait for a paint to do scrolly stuff
window.requestAnimationFrame(function() {
var node = _this.getDOMNode();
if (node !== undefined) {
//and scroll them!
node.scrollTop = node.scrollHeight;
}
});
},
componentDidMount: function() {
this.scrollElement();
},
// and or
componentDidUpdate: function() {
this.scrollElement();
},
// and or
render: function() {
this.scrollElement()
return [...]
From the ReactDOM.render() documentation: 从ReactDOM.render()文档中:
If the optional callback is provided, it will be executed after the component is rendered or updated. 如果提供了可选的回调,它将在呈现或更新组件之后执行。
In my experience window.requestAnimationFrame
wasn't enough to ensure that the DOM had been fully rendered / reflow-complete from componentDidMount
. 以我的经验, window.requestAnimationFrame
不足以确保DOM已从componentDidMount
完全渲染/重熔完成。 I have code running that accesses the DOM immediately after a componentDidMount
call and using solely window.requestAnimationFrame
would result in the element being present in the DOM; 我运行的代码在componentDidMount
调用之后立即访问DOM,并且仅使用window.requestAnimationFrame
会导致元素出现在DOM中; however, updates to the element's dimensions aren't reflected yet since a reflow hasn't yet occurred. 但是,由于尚未发生回流,因此尚未反映出元素尺寸的更新。
The only truly reliable way for this to work was to wrap my method in a setTimeout
and a window.requestAnimationFrame
to ensure React's current call stack gets cleared before registering for the next frame's render. 唯一真正可靠的方法是将我的方法包装在setTimeout
和window.requestAnimationFrame
以确保在注册下一帧渲染之前清除React的当前调用堆栈。
function onNextFrame(callback) {
setTimeout(function () {
requestAnimationFrame(callback)
})
}
If I had to speculate on why this is occurring / necessary I could see React batching DOM updates and not actually applying the changes to the DOM until after the current stack is complete. 如果我不得不猜测为什么会发生这种情况/有必要,我可以看到React批处理DOM更新,并且直到当前堆栈完成后才真正将更改应用于DOM。
Ultimately, if you're using DOM measurements in the code you're firing after the React callbacks you'll probably want to use this method. 最终,如果您在代码中使用DOM测量,则在React回调之后触发,您可能需要使用此方法。
After render, you can specify the height like below and can specify the height to corresponding react components. 渲染后,您可以指定如下高度,并可以为相应的反应组件指定高度。
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 (
);`
}
or you can specify the height of the each react component using sass. 或者您可以使用sass指定每个反应组件的高度。 Specify first 2 react component main div's with fixed width and then the third component main div's height with auto. 指定前2个具有固定宽度的react组件主div的高度,然后指定auto的第三个组件主div的高度。 So based on the third div's content the height will be assigned. 因此,将根据第三个div的内容指定高度。