React中如何通过父组件实现兄弟AgGrid组件的Ref跨注册?
实现AgGrid跨组件对齐的Ref管理方案
父组件X需承担ref统一管理的核心职责:收集A组件与当前激活B组件的AgGrid实例,再将对应ref传递给需要对齐的网格,通过配置alignedGrids属性实现官网的对齐效果。以下是具体实现步骤:
1. 父组件X:Ref与激活状态管理
在父组件中定义存储AgGrid实例的ref,同时管理当前激活的B组件标识,提供ref注册方法供子组件调用:
import { useRef, useState } from 'react'; function ParentX() { // 存储A组件的AgGrid API实例 const gridARef = useRef(null); // 存储当前激活B组件的AgGrid API实例 const activeGridBRef = useRef(null); // 记录当前激活的B组件ID const [activeBId, setActiveBId] = useState('b1'); // 子组件调用此方法注册AgGrid实例 const registerGridRef = (gridType, ref, bId) => { if (gridType === 'A') { gridARef.current = ref; } else if (gridType === 'B' && bId === activeBId) { activeGridBRef.current = ref; } }; // 切换激活B组件的逻辑 const switchActiveB = (newBId) => { setActiveBId(newBId); }; return ( <div> <ComponentA registerGridRef={registerGridRef} alignedGridRef={activeGridBRef.current} /> {/* 渲染所有B组件,根据activeBId控制激活状态 */} {['b1', 'b2', 'b3'].map(bId => ( <ComponentB key={bId} id={bId} isActive={bId === activeBId} registerGridRef={registerGridRef} alignedGridRef={gridARef.current} /> ))} <button onClick={() => switchActiveB('b1')}>激活B1</button> <button onClick={() => switchActiveB('b2')}>激活B2</button> </div> ); }
2. 组件A:注册自身Ref并接收对齐目标Ref
在组件A内部创建AgGrid的ref,挂载完成后将实例注册到父组件,同时使用父组件传递的激活B组件ref配置对齐:
import { useRef, useEffect } from 'react'; import { AgGridReact } from 'ag-grid-react'; function ComponentA({ registerGridRef, alignedGridRef }) { const gridRef = useRef(null); useEffect(() => { // AgGrid挂载完成后,获取API实例并注册到父组件 if (gridRef.current) { registerGridRef('A', gridRef.current.api); } // 组件卸载时清理ref return () => registerGridRef('A', null); }, [registerGridRef]); return ( <div className="ag-theme-alpine"> <AgGridReact ref={gridRef} // 你的列配置、数据源等其他属性 alignedGrids={alignedGridRef ? [alignedGridRef] : []} /> </div> ); }
3. 组件B:根据激活状态处理Ref注册
组件B需监听激活状态变化,仅在激活时将自身AgGrid实例注册到父组件,同时使用父组件传递的A组件ref配置对齐:
import { useRef, useEffect } from 'react'; import { AgGridReact } from 'ag-grid-react'; function ComponentB({ id, isActive, registerGridRef, alignedGridRef }) { const gridRef = useRef(null); useEffect(() => { if (isActive && gridRef.current) { // 激活时注册自身AgGrid实例 registerGridRef('B', gridRef.current.api, id); } else if (!isActive) { // 非激活时清理对应ref registerGridRef('B', null, id); } return () => registerGridRef('B', null, id); }, [isActive, id, registerGridRef]); // 非激活状态下可直接隐藏组件 if (!isActive) return null; return ( <div className="ag-theme-alpine"> <AgGridReact ref={gridRef} // 你的列配置、数据源等其他属性 alignedGrids={alignedGridRef ? [alignedGridRef] : []} /> </div> ); }
关键注意事项
- Ref传递时机:必须在AgGrid挂载完成后(
useEffect钩子中)传递ref,确保拿到的是有效的Grid API实例,而非组件本身。 - 激活切换的稳定性:切换激活B组件时,通过
key属性触发非激活组件卸载、激活组件重新挂载,确保ref注册逻辑正确执行。 - 内存泄漏防范:组件卸载或状态变化时,务必清理对应的ref引用,避免无效实例残留。
内容的提问来源于stack exchange,提问作者SkyWalker
相关产品推荐
相关产品推荐

