我正在尝试为一些React组件设置一个画布渲染系统(它们也可以在SVG中渲染,具体取决于它们的属性)。我还没有确定如何最好地做到这一点,但我目前采取的方法是在子组件上使用CanvasManager
组件和canvasContents
方法结合使用上下文并绘制它们预期内容。这样设置如下:
export default class CanvasManager extends React.Component {
constructor(...args) {
super(...args);
this.childElements = [];
this.canvasRender = this.canvasRender.bind(this);
}
componentDidMount(...args) {
super.componentDidMount && super.componentDidMount(...args);
this.canvasRender();
}
componentDidUpdate(...args) {
super.componentDidMount && super.componentDidMount(...args);
this.canvasRender();
}
canvasRender() {
const ctx = this.canvas.getContext('2d');
const { width, height } = this.props;
ctx.clearRect(0, 0, width, height);
this.childElements.forEach((child) => {
child.canvasContents(ctx);
});
}
render() {
const { width, height, positionStyle, children } = this.props;
const canvasChildren = React.Children.map(
children,
(child) => {
const props = extend({}, child.props, {
ref: (el) => {
if (el) { this.childElements.push(el); }
},
});
return extend({}, child, { props });
},
);
return (<div style={ positionStyle }>
<canvas
ref={ (canvas) => { this.canvas = canvas; } }
height={ height }
width={ width }
/>
{ canvasChildren }
</div>);
}
}
这里的想法是CanvasManager
将允许我根据需要处理画布的完全重绘,因此任何一个孩子获得新属性时,他们可以在{{1}上调用forceRender
并根据需要清除并重绘整个画布。
但是,孩子们的ref函数似乎永远不会触发,CanvasManager
总是一个空数组。 (由于我不理解的原因,它有时会触发this.childElements
,因此会发出el=null
语句。)如何在{{{{}}中访问我的子元素上的if
方法1}}?
(或者,如果有更好和完全不同的方式,我非常愿意接受这些想法。)