子组件触发事件修改父组件状态:仅保留点击项isSelected为true
实现子组件点击时更新父组件菜单选中状态的方案
你的需求是典型的单选菜单场景,当前代码的核心问题是把选中状态分散在了父组件和子组件中,导致子组件点击时无法同步更新整个父组件的menu数组。咱们通过「状态提升」来解决这个问题——把选中状态完全交给父组件管理,子组件只负责渲染和触发点击事件。
具体实现步骤:
- 移除子组件的本地状态:
MenuElem不需要自己维护isSelected,直接使用父组件传递的props即可,保证状态只有唯一来源。 - 父组件添加点击处理函数:编写
handleMenuClick方法,接收点击项的索引,遍历menu数组将所有项的isSelected设为false,仅把当前点击项设为true。 - 给子组件传递必要props:将
isSelected、点击回调onClick以及当前项的索引传递给每个MenuElem。
完整代码示例:
import React, { Component } from 'react'; class Parent extends Component { state = { menu: [ { isSelected: true }, { isSelected: false }, { isSelected: false } ] }; // 处理菜单点击的方法,接收点击项的索引 handleMenuClick = (index) => { this.setState(prevState => ({ // 遍历menu数组,更新每个项的isSelected状态 menu: prevState.menu.map((item, i) => ({ ...item, isSelected: i === index })) })); }; render() { return ( <div> {this.state.menu.map((menuItem, index) => ( <MenuElem key={index} isSelected={menuItem.isSelected} onClick={() => this.handleMenuClick(index)} /> ))} </div> ); } } class MenuElem extends Component { // 移除子组件的本地state,直接使用props传递的状态和事件 render() { const { isSelected, onClick } = this.props; return ( <div onClick={onClick} style={{ padding: '8px 16px', backgroundColor: isSelected ? '#165DFF' : '#f5f5f5', color: isSelected ? 'white' : 'black', cursor: 'pointer', margin: '4px 0', borderRadius: '4px' }} > 菜单选项 {isSelected ? '(已选中)' : ''} </div> ); } } export default Parent;
代码说明:
handleMenuClick使用了setState的函数式更新,确保基于最新的状态进行修改,避免异步更新导致的状态不一致问题。MenuElem变成了受控组件,它的选中状态完全由父组件的props控制,点击时仅需通知父组件触发状态更新,无需自己处理状态变化。- 给每个
MenuElem添加了key属性,符合React列表渲染的规范。
这样就能实现你需要的效果:点击任意子组件,父组件menu数组中所有项的isSelected都会设为false,仅被点击的项保持true。
内容的提问来源于stack exchange,提问作者Hyro
相关产品推荐
相关产品推荐

