gen*_*too 5 javascript svg reactjs
我正在使用标签渲染SVG组件.这些标签组件需要根据其文本内容(以及它们的大小)正确布局,以避免重叠.
为了获得每个标签的实际大小,每次更新标签内容时都需要双重渲染.
在标签组件级别,我需要
然后,在每次重绘时:
到目前为止,这是我如何实现我的标签组件:
var Label = React.createClass({
updateBBox: function() {
// Trigger re-rendering
this.setState({
bbox: this.getDOMNode().getBBox()
});
},
componentDidMount: function() {
// Will trigger a re-rendering at mount
this.updateBBox();
},
componentDidUpdate: function(prevProps, prevState) {
// If content has changed, re-render
if (this.props.content !== prevProps.content) {
this.updateBBox();
}
},
render: function() {
// Render according to size from current bounding box if any cached
// ...
}
});
Run Code Online (Sandbox Code Playgroud)
所以,我的问题不是关于算法,而是如果有更好的React兼容方式来实现它.使用状态缓存这种缓慢的"计算"还是以React方式允许的DOM访问?双重渲染是React的一个不寻常的案例吗?
我个人的观点是,你应该把所有重要的状态都放到一个组件的状态中.所以是的,你建议的方式是正确的方法.
据我所知,双重渲染是将块大小作为状态的唯一方法,因为需要首先绘制块.由于React是如此高效,这通常没有问题.如果是,则使用PureRenderMixin或对子节点内的shouldComponentUpdate进行其他检查以确保性能.
但请注意,将其写为mixin可能是明智之举,因为"不要重复自己".
我经常响应SVG的东西所以我经常需要块元素(svg或html)的x,y宽度和高度.
我写过这个叫做BoundingRectAware的小混音:
var shallowEqual = require('react/lib/shallowEqual');
// keep width and height of an element. You must make a "boundingRectTarget" ref
// to the element you would like to track
module.exports = {
getInitialState: function() {
return {rect: {
left: null, top: null, right: null, bottom: null, width: null, height: null
}};
},
componentDidMount: function() {
window.addEventListener("resize", this.updateDimensions);
this.updateDimensions();
},
componentWillUnmount: function() {
window.removeEventListener("resize", this.updateDimensions);
},
componentWillReceiveProps: function() {
this.updateDimensions();
},
updateDimensions: function() {
if (this.refs.boundingRectTarget) {
var rect = this.refs.boundingRectTarget.getDOMNode().getBoundingClientRect();
if (!shallowEqual(this.state.rect, rect)) {
this.setState({rect: rect});
}
}
}
};
Run Code Online (Sandbox Code Playgroud)
这可以这样使用:
var FooComponent = React.createClass({
mixins: [BoundingRectAware],
render: function() {
return <div className="foo-class" ref="boundingRectTarget"/>;
}
});
Run Code Online (Sandbox Code Playgroud)
在FooComponent中,您将自动获取boundingClientRect作为状态.如果你在多个地方使用getBBox(),我会实现类似的东西.
| 归档时间: |
|
| 查看次数: |
2717 次 |
| 最近记录: |