React状态提升时如何保留对下层组件计算变量的访问权限
解决方案
你完全不需要迁移Calendar的内部渲染逻辑,只需要提升共享状态、在中间层注入参数即可实现需求,核心调整只有两点:
- 状态提升仅需要同步「跨组件共享的状态」:也就是两个组件都需要用到的
当前选中方格序号,把它放到App层即可。Calendar自身的方格生成、排版渲染逻辑完全可以保留在组件内部,不需要向上迁移。 - 中间层注入参数的实现非常简单:App把点击处理函数作为prop传给Calendar后,Calendar在循环渲染Square的环节用箭头函数包一层,就能把当前的squareNum作为参数注入到方法里。
调整后示例代码
class App extends React.Component{ constructor(props){ super(props) // 仅存储跨组件共享的状态 this.state = { selectedSquareNum: null, renderedDate: new Date() // 保留你原有的日期计算逻辑 } // 绑定方法的this指向,也可以直接用箭头函数定义方法 this.handleSquareClick = this.handleSquareClick.bind(this) } handleSquareClick(squareNum){ // 点击后更新选中序号,同时可以计算对应的日期供侧边栏使用 this.setState({ selectedSquareNum: squareNum // 补充你自己的选中日期计算逻辑 }) } render(){ return ( <div> <Calendar renderedDate={this.state.renderedDate} onSquareClick={this.handleSquareClick} selectedSquareNum={this.state.selectedSquareNum} /> <Sidebar selectedDate={/* 此处传入你根据selectedSquareNum和renderedDate计算出的日期 */} /> </div> ) } } class Calendar extends React.Component{ constructor(props){ super(props) // 不需要再存储squares状态,直接通过props传入的选中状态判断样式即可 this.state = {} } renderSquare(squareNum){ const { onSquareClick, selectedSquareNum } = this.props return( <Square isSelected={selectedSquareNum === squareNum} // 用于点击后的视觉反馈 onClick={() => onSquareClick(squareNum)} // 这里注入当前方格的序号参数 /> ) } render(){ let squareNum = 0; let cal = []; for(let i=0;i<5;i++){ let row = []; for (let j=0;j<7;j++){ row.push(this.renderSquare(squareNum)); squareNum++; } cal.push(<div key={i} className="calendar-row">{row}</div>); } return <div className="calendar">{cal}</div> } } function Square(props){ // 用isSelected参数控制选中样式即可 return ( <div className={`square ${props.isSelected ? 'selected' : ''}`} onClick={props.onClick} > {/* 方格原有内容逻辑 */} </div> ) }
如果Calendar内部还有仅自身使用的状态,可以继续保留在Calendar内部,不需要做任何调整,仅提升跨组件共享的状态即可。
内容的提问来源于stack exchange,提问作者Ryan Thomas
相关产品推荐
相关产品推荐

