React中如何用useState实现Footer组件的条件式主题切换?
核心问题分析
你的代码里有两个关键错误导致主题不生效:
- Props传递不匹配:Footer组件声明接收
themeSecondary属性,但Home和Location组件调用时传的是theme,导致Footer根本拿不到主题状态值 - 不必要的useEffect引发无限循环:Home和Location里的useEffect依赖了
themeSecondary,同时在内部又调用setThemeSecondary,会触发无限重渲染,而且完全没必要用useEffect来初始化状态
修复步骤
1. 修正Props传递
把Home和Location中Footer的调用参数从theme改成themeSecondary:
// Home组件里的Footer调用 <Footer themeSecondary={themeSecondary} /> // Location组件里的Footer调用 <Footer themeSecondary={themeSecondary} />
2. 移除冗余的useEffect,直接初始化状态
Home和Location里的useEffect完全多余,直接在useState里设置初始值即可,同时避免无限循环:
// Home组件修正 function Home() { // 直接初始化为false,不需要useEffect const [themeSecondary, setThemeSecondary] = useState(false) return ( // ... 其他代码不变 <Footer themeSecondary={themeSecondary} /> ) } // Location组件修正 function Location() { // 直接初始化为true const [themeSecondary, setThemeSecondary] = useState(true) return ( <div className="location"> <Footer themeSecondary={themeSecondary} /> </div> ) }
3. 可选优化:用CSS类替代内联样式(更易维护)
内联样式虽然能生效,但后续扩展主题会比较麻烦,建议改成通过CSS类控制:
/* 基础Footer样式 */ .footer { /* 公共样式,比如 padding、字体等 */ } /* 深色主题 */ .footer--dark { background-color: #151515; } .footer--dark .footer__desc { color: #FFF; } /* Secondary主题 */ .footer--secondary { background-color: #D5966C; } .footer--secondary .footer__desc { color: #151515; } .footer--secondary .footer__media-container { filter: invert(1); }
然后修改Footer组件:
function Footer({ themeSecondary }) { return ( <footer className={`footer ${themeSecondary ? 'footer--secondary' : 'footer--dark'}`} > <img src={themeSecondary ? 'assets/logo-dark.svg' : 'assets/logo-light.svg'} alt="Modern Art Gallery" className="footer__logo" /> <p className="footer__desc"> The Modern Art Gallery is free to all visitors and open seven days a week from 8am to 9pm. Find us at 99 King Street, Newport, USA. </p> <ul className="footer__media-container"> {/* 媒体图标代码保持不变 */} <li className="footer__media-icon"> <a href="https://www.facebook.com" target="_blank" rel="noreferrer"> <img src="/assets/icon-facebook.svg" alt="facebook" /> </a> </li> <li className="footer__media-icon"> <a href="https://www.instagram.com" target="_blank" rel="noreferrer"> <img src="/assets/icon-instagram.svg" alt="instagram" /> </a> </li> <li className="footer__media-icon"> <a href="https://www.twitter.com" target="_blank" rel="noreferrer"> <img src="/assets/icon-twitter.svg" alt="twitter" /> </a> </li> </ul> </footer> ) }
测试验证
修复后,Home页面的Footer会使用深色主题,Location页面会使用Secondary主题,切换页面时主题会自动匹配对应的状态。
内容的提问来源于stack exchange,提问作者Kade
相关产品推荐
相关产品推荐

