Reactjs ag grid react使用钩子会导致在某些环境中重新安装组件
长话短说:在某些使用react-useState钩子的环境中,ag网格会自我刷新。它的行为就像组件是从头开始重新安装的,所以您失去了滚动位置等。我使用的是infinte滚动模式,但无论滚动类型如何,都存在相同的行为。 在下面的示例中,我尝试使用useState钩子来更新onViewportChanged回调中的自定义div:Reactjs ag grid react使用钩子会导致在某些环境中重新安装组件,reactjs,react-hooks,ag-grid,Reactjs,React Hooks,Ag Grid,长话短说:在某些使用react-useState钩子的环境中,ag网格会自我刷新。它的行为就像组件是从头开始重新安装的,所以您失去了滚动位置等。我使用的是infinte滚动模式,但无论滚动类型如何,都存在相同的行为。 在下面的示例中,我尝试使用useState钩子来更新onViewportChanged回调中的自定义div: function Grid({ columnDefinition, config }) { const domInfoRef = useRef(null); const
function Grid({ columnDefinition, config }) {
const domInfoRef = useRef(null);
const [actualRange, setActualRange] = useState({ from: null, to: null, total: null });
function onViewportChanged(data) {
if (config.paginationStyle === 'scroll' && domInfoRef.current) {
const renderedNodes = data.api.getRenderedNodes();
const firstIndex = renderedNodes[0].rowIndex;
const lastIndex = renderedNodes[renderedNodes.length - 1].rowIndex;
/*
React "useState" inside AG grid callbacks causes unstable behaviour and refresh of component
on some environments.
This not works:
setActualRange({from: firstIndex + 1, to: ${lastIndex + 1}, total: data.api.getDisplayedRowCount()})
In order to update status there is necessary to do this using plain js as below.
*/
// update page-info after scrolling in "scroll" pagination style
domInfoRef.current.textContent = `${firstIndex + 1} - ${lastIndex + 1} of ${data.api.getDisplayedRowCount()}`;
}
}
return (
<Fragment>
<div className={`page-info`}>
<span ref={domInfoRef}>
{actualRange.from} - {actualRange.to} of {actualRange.total}
</span>
</div>
<AgGridReact
pagination={false}
paginationPageSize={config.itemsPerPage}
cacheBlockSize={config.itemsPerPage}
maxBlocksInCache={config.itemsPerPage}
rowModelType={'serverSide'}
rowData={gridData}
onGridReady={onGridReady}
serverSideDatasource={createDataSource()}
serverSideStoreType={'partial'}
rowSelection='single'
onViewportChanged={onViewportChanged}
blockLoadDebounceMillis={100}
>
{columnDefinition.map((column) => {
return (
<AgGridColumn
headerName={column.headerName}
field={column.field}
suppressMenu={true}
sortable={column.sortable}
key={column.field}
resizable={column.resizable}
onCellClicked={column.onCellClicked}
cellRenderer={renderers[column.field] ? column.field : null}
valueFormatter={column.valueFormatter ?? null}
suppressSizeToFit={column.suppressSizeToFit}
></AgGridColumn>
);
})}
</AgGridReact>
</Fragment>;
}
);
函数网格({columnDefinition,config}){
const domInfoRef=useRef(null);
const[actualRange,setActualRange]=useState({from:null,to:null,total:null});
已更改ViewPort上的函数(数据){
if(config.paginationStyle=='scroll'&&domInfoRef.current){
const renderedNodes=data.api.getRenderedNodes();
const firstIndex=renderedNodes[0]。行索引;
const lastIndex=renderedNodes[renderedNodes.length-1].rowIndex;
/*
AG网格回调中的React“useState”会导致组件行为不稳定和刷新
在某些环境中。
这不起作用:
setActualRange({from:firstIndex+1,to:${lastIndex+1},总计:data.api.getDisplayedRowCount()})
为了更新状态,有必要使用普通js进行更新,如下所示。
*/
//以“滚动”分页方式滚动后更新页面信息
domInfoRef.current.textContent=`${data.api.getDisplayedRowCount()}`的${firstIndex+1}-${lastIndex+1};
}
}
返回(
{actualRange.from}-{actualRange.to}的{actualRange.total}
{columnDefinition.map((列)=>{
返回(
);
})}
;
}
);
如果我使用react-inside-cell renderers函数(当然是在frameworkComponents内部的ag grid中注册该渲染之后),情况也是一样的。单独渲染和网格中的所有其他功能(如排序等)都可以正常工作。但我真的不知道是什么原因导致了这个问题。AG网格版本为25.2.0,React版本为16.14.0。提前感谢您提供的任何线索。我试着用备忘录,但没有成功。最奇怪的是,它在某些环境下运行良好,不依赖于浏览器或操作系统。解决方法:
将AGGrid包装到useState钩子中:
const [grid, setGrid] = useState(null);
const agGrid = () =>{
return(
<AgGridReact
pagination={false}
paginationPageSize={config.itemsPerPage}
cacheBlockSize={config.itemsPerPage}
maxBlocksInCache={config.itemsPerPage}
rowModelType={'serverSide'}
rowData={gridData}
onGridReady={onGridReady}
serverSideDatasource={createDataSource()}
serverSideStoreType={'partial'}
rowSelection='single'
onViewportChanged={onViewportChanged}
blockLoadDebounceMillis={100}
>
{columnDefinition.map((column) => {
return (
<AgGridColumn
headerName={column.headerName}
field={column.field}
suppressMenu={true}
sortable={column.sortable}
key={column.field}
resizable={column.resizable}
onCellClicked={column.onCellClicked}
cellRenderer={renderers[column.field] ? column.field : null}
valueFormatter={column.valueFormatter ?? null}
suppressSizeToFit={column.suppressSizeToFit}
></AgGridColumn>
);
})}
</AgGridReact>
)
}
useEffect(() => {
setGrid(<agGrid/>);
}, []);
return (
<Fragment>
<div className={`page-info`}>
<span ref={domInfoRef}>
{actualRange.from} - {actualRange.to} of {actualRange.total}
</span>
</div>
{grid}
</Fragment>;
}
)
const[grid,setGrid]=useState(null);
常量agGrid=()=>{
返回(
{columnDefinition.map((列)=>{
返回(
);
})}
)
}
useffect(()=>{
setGrid();
}, []);
返回(
{actualRange.from}-{actualRange.to}的{actualRange.total}
{grid}
;
}
)
说明:
此解决方案强制每个组件生命周期使用单个(相同)AG网格实例。在我看来,它应该被视为黑客,但它正在发挥作用