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

React项目启用明暗模式时遇Cannot read properties of undefined错误求助

问题排查与解决

错误根源

你犯了React Hook的基础用法错误:useState返回的是数组,不是对象,你用了对象解构语法const {myStyle, setMyStyle} = useState(...),这会导致myStyle和setMyStyle都变成undefined,自然无法读取myStyle.color。

修复方法

把对象解构改成数组解构,将{}替换为[]即可:

// 错误写法
const {myStyle, setMyStyle} = useState({
    color: 'black',
    backgroundColor: 'white'
})

// 正确写法
const [myStyle, setMyStyle] = useState({
    color: 'black',
    backgroundColor: 'white'
})

修正后的完整代码

import React, {useState} from 'react'

export default function About() {

    const [myStyle, setMyStyle] = useState({
        color: 'black',
        backgroundColor: 'white'
    })
    const [btntext, setBtnText] = useState("Enable Dark Mode")

    const toggleStyle = ()=>{
        if(myStyle.color === 'black'){
            setMyStyle({
                color: 'white',
                backgroundColor: 'black',
            })
            setBtnText("Enable Light Mode")
        }
        else{
            setMyStyle({
                color: 'black',
                backgroundColor: 'white',
            })
            setBtnText("Enable Dark Mode");
        }
    }

  return (
        <div className ="container" style={myStyle}>
            <h1 className='my-3'>About us</h1>
            <div className="accordion accordion-flush" id="accordionFlushExample" style={myStyle}>
                <div className="accordion-item">
                 <h2 className="accordion-header">
            <button className="accordion-button collapsed" type="button" style={myStyle} data-bs-toggle="collapse" data-bs-target="#flush-collapseOne" aria-expanded="false" aria-controls="flush-collapseOne">
                Accordion Item #1
            </button>
            </h2>
            <div id="flush-collapseOne" className="accordion-collapse collapse" data-bs-parent="#accordionFlushExample">
            <div className="accordion-body" style={myStyle}>Placeholder content for this accordion, which is intended to demonstrate the <code>.accordion-flush</code> className. This is the first item's accordion body.</div>
            </div>
                 </div>
            <div className="accordion-item"> 
            <h2 className="accordion-header">
            <button className="accordion-button collapsed" type="button" style={myStyle} data-bs-toggle="collapse" data-bs-target="#flush-collapseTwo" aria-expanded="false" aria-controls="flush-collapseTwo">
                Accordion Item #2
            </button>
            </h2>
            <div id="flush-collapseTwo" className="accordion-collapse collapse" data-bs-parent="#accordionFlushExample">
            <div className="accordion-body" style={myStyle}>Placeholder content for this accordion, which is intended to demonstrate the <code>.accordion-flush</code> className. This is the second item's accordion body. Let's imagine this being filled with some actual content.</div>
            </div>
        </div>
        <div className="accordion-item">
            <h2 className="accordion-header">
            <button className="accordion-button collapsed" type="button" style={myStyle} data-bs-toggle="collapse" data-bs-target="#flush-collapseThree" aria-expanded="false" aria-controls="flush-collapseThree">
                Accordion Item #3
            </button>
            </h2>
            <div id="flush-collapseThree" className="accordion-collapse collapse" data-bs-parent="#accordionFlushExample">
            <div className="accordion-body" style={myStyle}>Placeholder content for this accordion, which is intended to demonstrate the <code>.accordion-flush</code> className. This is the third item's accordion body. Nothing more exciting happening here in terms of content, but just filling up the space to make it look, at least at first glance, a bit more representative of how this would look in a real-world application.</div>
            </div>
        </div>
            </div>
            <div className="container my-3">
            <button onClick={toggleStyle} type ="button" className="btn btn-primary">{btntext}</button>
            </div>
         </div>
  )
}

额外优化建议

  • 如果后续样式属性增多,建议使用className切换而非直接修改内联样式,这样更便于维护(比如定义.dark-mode和.light-mode类)。
  • 可以用useCallback包裹toggleStyle函数,避免组件重渲染时重复创建该函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 11:58:12