React中如何在两个div(或两个点)之间绘制连接线?
React实现任意Div圆点间连线的方案
3×3网格排列的9个圆形,其中3个圆形通过随机线条连接至其他圆形(示例图)
最推荐:零依赖SVG叠加层方案
不需要引入任何第三方库,天然支持水平、垂直、任意角度斜线,逻辑完全可控,不会出现第三方库不渲染的问题。
实现逻辑
- 外层3x3网格容器设置
position: relative - 容器内部嵌入和容器尺寸完全一致的SVG层,设置
position: absolute; top: 0; left: 0; pointer-events: none,z-index低于圆点,避免遮挡交互 - 所有圆点设置
position: relative,z-index高于SVG层,保证圆点显示在连线之上 - DOM渲染完成后,获取每对需要连接的圆点的中心坐标(相对于SVG容器的偏移量),直接在SVG内绘制
<line>标签即可
最小可运行代码示例
import { useEffect, useRef, useState } from 'react' // 3x3网格圆点配置 const dotList = [ { id: 1, row: 0, col: 0 }, { id: 2, row: 0, col: 1 }, { id: 3, row: 0, col: 2 }, { id: 4, row: 1, col: 0 }, { id: 5, row: 1, col: 1 }, { id: 6, row: 1, col: 2 }, { id: 7, row: 2, col: 0 }, { id: 8, row: 2, col: 1 }, { id: 9, row: 2, col: 2 }, ] // 需要连线的圆点ID对 const connectPairs = [[1, 5], [5, 9], [3, 7]] export default function DotGrid() { const gridRef = useRef(null) const dotDomRefs = useRef({}) const [lineConfigs, setLineConfigs] = useState([]) useEffect(() => { const gridRect = gridRef.current.getBoundingClientRect() const lines = connectPairs.map(([fromId, toId]) => { const fromDom = dotDomRefs.current[fromId] const toDom = dotDomRefs.current[toId] const fromRect = fromDom.getBoundingClientRect() const toRect = toDom.getBoundingClientRect() // 计算两个圆点相对于SVG画布的中心坐标 return { x1: fromRect.left - gridRect.left + fromRect.width / 2, y1: fromRect.top - gridRect.top + fromRect.height / 2, x2: toRect.left - gridRect.left + toRect.width / 2, y2: toRect.top - gridRect.top + toRect.height / 2, } }) setLineConfigs(lines) }, []) return ( <div ref={gridRef} className="grid grid-cols-3 gap-16 p-8 relative w-fit" > {/* SVG连线层 */} <svg className="absolute top-0 left-0 w-full h-full pointer-events-none" style={{ zIndex: 0 }} > {lineConfigs.map((line, idx) => ( <line key={idx} x1={line.x1} y1={line.y1} x2={line.x2} y2={line.y2} stroke="#222" strokeWidth="2" /> ))} </svg> {/* 圆点层 */} {dotList.map(dot => ( <div key={dot.id} ref={dom => (dotDomRefs.current[dot.id] = dom)} className="w-8 h-8 rounded-full bg-gray-900" style={{ zIndex: 1 }} /> ))} </div> ) }
如果是固定布局的静态连线,甚至不需要动态计算DOM坐标,直接根据网格的单元格宽高、间距写死连线坐标即可,代码会更简洁。这个方案支持自定义线的样式,虚线、渐变、箭头、连线动画都可以直接通过SVG属性实现。
备选:成熟第三方连线库
如果后续需要支持拖拽连线、元素拖动时连线自动跟随、连线避障等复杂交互,可以选择维护状态更好的库:
reactflow:功能最完善的React节点连线库,适合做流程图、拓扑图类场景react-konva:基于Canvas的绘图库,如果需要大量连线、图形元素时性能比SVG更好
之前react-lineto不渲染的常见原因
你之前写的测试代码不渲染,基本是几个低级问题导致的:
- 对应
from、to类名的元素没有设置position: relative,库无法获取正确的元素位置 <LineTo />组件没有放在两个目标元素的共同父容器内部- 类名为
B的div没有设置宽高,嵌套的空div没有承接类名,库无法定位到目标元素
内容的提问来源于stack exchange,提问作者reactup
相关产品推荐
相关产品推荐

