我有一个应用程序,我需要动态设置一个元素的高度(让我们说“app-content”)。它取应用程序的“chrome”的高度并减去它,然后设置“app-content”的高度以100%符合这些限制。这是超级简单的香草JS, jQuery,或骨干视图,但我努力弄清楚正确的过程将在React中这样做?
下面是一个示例组件。我想要能够设置应用内容的高度为窗口的100%减去动作栏和BalanceBar的大小,但我怎么知道什么时候所有的渲染和哪里我将把计算的东西在这个反应类?
/** @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组件并在画布上绘制时,我遇到了奇怪的情况。我已经尝试了所有提到的方法,它们都不可靠地为我工作,与requestAnimationFrame内setTimeout我得到空画布在20%的时间,所以我做了以下工作:
nRequest = n => range(0,n).reduce(
(acc,val) => () => requestAnimationFrame(acc), () => requestAnimationFrame(this.save)
);
基本上我做了一个requestAnimationFrame的链,不确定这是好主意还是不好,但这在100%的情况下为我到目前为止(我使用30作为n变量的值)。
对于功能性组件,您可以react-use-call-onnext-render,它是一个自定义钩子,允许在以后的渲染上安排回调。
在我的另一个项目中成功地使用了它。
如果需要dom元素的维度,
请看这个例子,它是react-use-call-onnext-render例子的第三个例子:
假设我们想要获取一个可移动DOM元素的尺寸,假设是由showBox状态控制的div
变量。为此,我们可以使用getBoundingClientRect()。但是,我们希望只在元素之后调用这个函数
挂载到dom中,因此将调度此调用在负责显示此元素的变量之后渲染一次
在dom中已经改变了,这个变量是showBox,所以他将是useCallOnNextRender的依赖:
const YourComponent = () => {
const [showBox, setShowBox] = useState(false)
const divRef = useRef()
const callOnNextShowBoxChange = useCallOnNextRender()
return (
<>
<div style={canvasStyle} id="canvas">
<button style={boxStyle} onClick={() => {
setShowBox(!showBox)
callOnNextShowBoxChange(() => console.log(divRef.current.getBoundingClientRect())) //right value
}}>toggle show box
</button>
<div style={{border: "black solid 1px"}} ref={divRef}>
{showBox ? <div style={boxStyle}>box2</div> : null}
</div>
</div>
</>
);
};
我也遇到了同样的问题。
在大多数情况下,在componentDidMount()中使用类似hack的setTimeout(() =>{}, 0)是有效的。
但不是在特殊情况下;我不想使用ReachDOM findDOMNode,因为文档说:
注意:findDOMNode是一个用于访问底层DOM的escape hatch
节点。在大多数情况下,不鼓励使用这个逃生口,因为
它穿透了组件抽象。
(来源:findDOMNode)
所以在那个特定的组件中,我必须使用componentDidUpdate()事件,所以我的代码最终是这样的:
componentDidMount() {
// feel this a little hacky? check this: http://stackoverflow.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));
}