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

React状态控制交替显示按钮失效问题求助

React组件按钮切换仅首次生效的问题排查与修复

问题根源

你的代码存在闭包陷阱导致状态更新失效:

  • handleState 和 noHandleState 函数中调用 setCheckAll 时,直接使用了当前渲染周期捕获的 isCheckAll 初始值(true)。当组件首次切换状态后,这两个函数里的 isCheckAll 并未同步更新为最新状态,后续点击时,状态更新逻辑始终基于旧值,导致无法正确触发切换。
  • 比如第一次点击「모두 접기」后,isCheckAll 变为 false,但此时 noHandleState 里的 isCheckAll 还是初始的 true,执行 setCheckAll(true===true) 相当于把状态设回 true,没有实质变化,组件不会重新渲染,后续点击自然无响应。

修复方案

1. 使用函数式更新状态

React 的 setState 支持传入函数,函数会接收最新的状态值作为参数,确保每次更新都基于当前最新状态,彻底避免闭包问题。

2. 简化点击逻辑

不需要两个独立的处理函数,一个函数即可完成状态取反操作,减少冗余代码。

修改后的代码

import React, { useState } from 'react'
import styled from 'styled-components';

const Body3LeftStart = styled.div`
  flex-basis: 66.66666667% !important;
  max-width: 66.66666667%;
  box-sizing: border-box;
  flex: 0 0 auto;
  padding-left: 8px;
  padding-right: 8px;
`
const Body3LeftSection = styled.div`
  margin-bottom: 8px;
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.5;
  color: #000a12;
  box-sizing: border-box;
  font-family: Pretendard,-apple-system,BlinkMacSystemFont,system-ui,Roboto,Helvetica Neue,Segoe UI,Apple SD Gothic Neo,Noto Sans KR,Malgun Gothic,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,sans-serif;

  #Body3Section1 {
    display: flex;
    align-items: flex-end;
    margin-bottom: 8px;
  }
`

const Body3LeftSection2 = styled.div`
  display: flex;
    margin-bottom: 20px;
    align-items: flex-end;

    #Body3LeftSection2Text {
      font-weight: 400;
    line-height: 1.47;
    letter-spacing: -.3px;
    font-size: 15px;
    margin-right: 12px;
    color: #495057;
    word-break: keep-all;
    }

    .Body3LeftSection2Button {
      border-color: #d5dbe2;
    color: #495057;
    background-color: #fff;
    flex-shrink: 0;
    margin-left: auto;
    border: 1px solid;
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 4px;
    font-weight: 500;
    cursor: pointer;
    -webkit-appearance: none;
    padding: 0 12px;
    height: 40px;
    line-height: 1.43;
    font-size: 14px;
    letter-spacing: -.3px;
    }
`

function Body3Left() {

  const [isCheckAll, setCheckAll] = useState(true)

  // 统一处理状态切换
  function toggleExpandState() {
    setCheckAll(prevState => !prevState)
  }

  return (
    <Body3LeftStart>
        <Body3LeftSection>
            <Body3LeftSection2>
              <span id='Body3LeftSection2Text'>
                이 강의는 영상, 수업 노트가 제공됩니다. 미리보기를 통해 콘텐츠를 확인해보세요.
              </span>
              <button 
                onClick={toggleExpandState} 
                style={{display: isCheckAll ? 'block' : 'none'}} 
                className='Body3LeftSection2Button'
              >
                모두 접기
              </button>
              <button 
                onClick={toggleExpandState} 
                style={{display: isCheckAll ? 'none' : 'block'}} 
                className='Body3LeftSection2Button'
              >
                모두 펼치기
              </button>
            </Body3LeftSection2>   
        </Body3LeftSection>
    </Body3LeftStart>
  )
}

export default Body3Left;

额外优化提示

  • 移除了重复的 id(HTML 中 id 必须唯一),改用类名控制样式,避免潜在的样式或选择器冲突。
  • 简化了 display 属性的判断逻辑,让代码更直观易读。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 09:01:33