我需要从UV坐标渲染React子组件(规范化坐标/ U和V通常在[0; 1]范围内)
但是我不知道在渲染儿童时如何获得父尺寸。
我想执行类似的操作(使用tsx):
const Child = (props: {u:Number, v:Number}) =>
<circle cx={parentClientWidth*props.u} cy={parentClientHeight*props.v} r="5" fill="black"></circle>;
const Parent = () =>
<svg>
<Child u={0.3} v={0.5} />
</svg>;
我愿意使用上下文对象吗?...
const Child = (props: {u:Number, v:Number}) => {
const workspace= useContext(WorkspaceContext);
return <circle cx={workspace.width*u} cy={workspace.height*v} r="5"></circle>;
}
注意: 在这种简单的情况下,我可以将百分数用于cx和cy坐标,但实际情况要复杂得多...
答案 0 :(得分:0)
在研究了很多反应文档之后,我终于找到了一种对我来说似乎不太hacky的方法……但是我仍在学习,因此可能还有另一种更好的方法(关于性能?可读性?……) 无论如何,这是我当前解决方案的想法:
// Shares the dimensions of the workspace through children
const WorkspaceContext = createContext();
/** A child component.
* It should be placed at specified (u,v) within the parent component.
*/
const Child = (props: {u:Number, v:Number}) => {
const workspaceContext = useContext(WorkspaceContext);
return <circle cx={workspaceContext.width*props.u} cy={workspaceContext.height*props.v} r="5" fill="black"></circle>;
};
/** The parent SVG component */
const Parent = () => {
const [dimensions, setDimensions] = useState({
width: undefined,
height:undefined,
outdated: true // Triggers a re render when changed
});
// I'm using the ref callback to get the svg dimensions
const parentRefCallback = (element: SVGSVGElement) => {
if(element) {
const width = element.clientWidth;
const height = element.clientHeight;
if(dimensions.width !== width || dimensions.height !== height) {
setDimensions({width, height, outdated: false});
}
}
};
useEffect(() => {
const handler = () => setDimensions({...dimensions, outdated: true}); // re renders!
window.addEventListener('resize', handler);
return () => window.removeEventListener('resize', handler);
}, [])
return <svg ref={parentRefCallback}>
<WorkspaceContext.Provider value={dimensions}>
<Child u={0.3} v={0.5} />
</WorkspaceContext.Provider>
</svg>;
}