如何在不修改react-window的Grid组件时,向独立cellRenderer传handleIncrement?
可行的解决方案推荐
这问题我之前碰到过类似的,react-window的组件源码咱们动不了,但完全有办法让抽离后的cellRenderer组件拿到父组件的handleIncrement方法,给你推荐两个最实用的方案:
方案一:利用闭包传递方法(最直接)
核心思路是在你的App组件里,给react-window的Grid组件传cellRenderer的时候,做一层包装函数,把父组件的handleIncrement作为参数传给抽离后的独立组件。因为cellRenderer本身就是一个接受props的函数,咱们完全可以在这个函数里把需要的方法塞进去。
代码示例:
首先是抽离后的独立Cell组件:
// Cell.jsx export default function Cell({ columnIndex, rowIndex, style, handleIncrement }) { // 这里就能直接用handleIncrement了 if (rowIndex === 2 && columnIndex === 0) { return ( <div style={style} onClick={handleIncrement}> no.3 </div> ); } return <div style={style}>Cell {rowIndex}-{columnIndex}</div>; }
然后是你的App类组件:
// App.jsx import { Grid } from 'react-window'; import Cell from './Cell'; class App extends React.Component { state = { x: 0 }; handleIncrement = () => { this.setState(prevState => ({ x: prevState.x + 1 }), () => { console.log('x updated:', this.state.x); }); }; render() { return ( <Grid columnCount={1} columnWidth={100} height={300} rowCount={5} rowHeight={50} width={300} // 这里做一层包装,把handleIncrement传给Cell组件 cellRenderer={props => <Cell {...props} handleIncrement={this.handleIncrement} />} /> ); } }
这个方案的优点是简单直接,不需要额外的API,完全利用React的props传递和闭包特性,而且完全兼容react-window的用法。
方案二:使用React Context(适合复杂场景)
如果你的项目里有很多类似的组件需要共享这个方法,或者组件层级比较深,用Context会更优雅。我们可以创建一个Context,在App组件里提供handleIncrement,然后在Cell组件里消费这个Context。
代码示例:
首先创建Context:
// IncrementContext.jsx import React from 'react'; const IncrementContext = React.createContext(null); export default IncrementContext;
然后修改App组件,用Context.Provider包裹Grid:
// App.jsx import { Grid } from 'react-window'; import Cell from './Cell'; import IncrementContext from './IncrementContext'; class App extends React.Component { state = { x: 0 }; handleIncrement = () => { this.setState(prevState => ({ x: prevState.x + 1 }), () => { console.log('x updated:', this.state.x); }); }; render() { return ( <IncrementContext.Provider value={this.handleIncrement}> <Grid columnCount={1} columnWidth={100} height={300} rowCount={5} rowHeight={50} width={300} cellRenderer={props => <Cell {...props} />} /> </IncrementContext.Provider> ); } }
最后修改Cell组件,消费Context:
// Cell.jsx import React from 'react'; import IncrementContext from './IncrementContext'; export default function Cell({ columnIndex, rowIndex, style }) { const handleIncrement = React.useContext(IncrementContext); if (rowIndex === 2 && columnIndex === 0) { return ( <div style={style} onClick={handleIncrement}> no.3 </div> ); } return <div style={style}>Cell {rowIndex}-{columnIndex}</div>; }
这个方案适合需要在多个组件共享方法的场景,不用一层一层传递props,代码更整洁。
内容的提问来源于stack exchange,提问作者Kaya Toast
相关产品推荐
相关产品推荐

