You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React点击子组件激活时其余兄弟组件自动取消选中的实现咨询

React 单选进度栏实现方案

核心思路

你之前的第二种思路是正确的,将选中状态提升到父组件维护完全符合React单向数据流原则:数据从父组件通过props向下流向子组件,子组件通过父组件传递的回调函数向上传递操作意图,父组件更新状态后重新下发props,整个流程单向可控,是React官方推荐的兄弟组件通信方案。

你之前的代码存在两个核心问题:

  1. 子组件各自维护独立的选中状态,父组件无法感知也无法同步其他子组件的状态
  2. 子组件点击逻辑存在冗余错误,连续两次setState的写法不符合异步更新规则

修正后完整代码

父组件 ProgressBar

class ProgressBar extends React.Component {
    constructor(props) {
        super(props);
        // 父组件统一维护当前选中的进度项类型,默认选中第一个pattern
        this.state = {
            selectedType: "pattern"
        }
        this.handleSelect = this.handleSelect.bind(this);
    }

    // 接收子组件传递的选中类型,更新父组件状态
    handleSelect(type) {
        this.setState({
            selectedType: type
        })
    }

    render() {
        return <div className="d-flex custom-progress-bar">
            <ProgressElement 
                eleType="pattern"
                isSelected={this.state.selectedType === "pattern"}
                onSelect={this.handleSelect}
            />
            <ProgressElement 
                eleType="gift"
                isSelected={this.state.selectedType === "gift"}
                onSelect={this.handleSelect}
            />
            <ProgressElement 
                eleType="personal"
                isSelected={this.state.selectedType === "personal"}
                onSelect={this.handleSelect}
            />
        </div>
    }
}

子组件 ProgressElement

class ProgressElement extends React.Component {
    constructor(props) {
        super(props);
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick() {
        // 点击时调用父组件传递的回调,将自身类型传递给父组件
        this.props.onSelect(this.props.eleType);
    }

    render() {
        let eleNumber = NaN;
        if (this.props.eleType === "pattern") eleNumber = 1;
        if (this.props.eleType === "gift") eleNumber = 2;
        if (this.props.eleType === "personal") eleNumber = 3;

        // 选中状态完全由父组件传递的isSelected prop控制
        return <div 
            className={`square-box ${this.props.isSelected ? 'selected' : ''}`}
            onClick={this.handleClick}
        >
            {eleNumber}
        </div>
    }
}

逻辑说明

  • 父组件维护唯一的选中状态源,避免了多个子组件状态不同步的问题
  • 子组件完全成为受控组件,只负责视图渲染和点击事件触发,不需要维护内部状态
  • 点击任意子组件时,父组件更新选中状态后自动重新渲染所有子组件,仅当前点击的子组件会拿到isSelected=true的属性,其余自动变为未选中状态,满足单选需求

内容的提问来源于stack exchange,提问作者Flo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 13:24:03