如何在React模态窗口中根据订阅状态切换渲染不同内容
问题根因
- 你使用普通全局对象存储订阅状态,不属于React的响应式状态,修改后不会触发组件重渲染,视图无法同步更新。
- 模态框内的条件判断逻辑错误:你写了两个满足
!state.isSubscriptionEnabled就渲染的内容块,只要订阅处于禁用状态,两个块会同时显示,符合你现在遇到的问题。
修复方案
- 把订阅状态改为React内置的
useState管理,保证状态修改后触发组件重渲染 - 调整模态框的条件判断逻辑,根据操作场景区分展示内容,同一时间只渲染一个内容块
修复后JS代码
const { useState } = React; function App() { // 用useState管理响应式状态 const [isOpen, setIsOpen] = useState(false) const [isSubscriptionEnabled, setIsSubscriptionEnabled] = useState(true) // 新增状态区分模态框展示场景:disableConfirm(确认禁用)/disableSuccess(禁用成功)/enableConfirm(确认启用) const [modalScene, setModalScene] = useState('disableConfirm') const enableSub = () => { setIsSubscriptionEnabled(true) setIsOpen(false) } const disableSub = () => { setIsSubscriptionEnabled(false) // 禁用后切换到成功提示场景 setModalScene('disableSuccess') } return ( <div> {isOpen && <div className="modalWrapper"> <div className="modal"> <button onClick={() => setIsOpen(false)}>close</button> <div> {/* 确认禁用场景 */} {modalScene === 'disableConfirm' && <div> 你确定要禁用订阅吗? <button className="button" onClick={disableSub}> 禁用订阅 </button> </div> } {/* 禁用成功场景 */} {modalScene === 'disableSuccess' && <div> 订阅已成功禁用 <button onClick={() => setIsOpen(false)}> 谢谢 </button> </div> } {/* 确认启用场景 */} {modalScene === 'enableConfirm' && <div> 点击下方按钮启用订阅 <button className="button" onClick={enableSub}> 启用订阅 </button> </div> } </div> </div> </div> } {isSubscriptionEnabled && <button className="button" onClick={() => { setModalScene('disableConfirm') setIsOpen(true) }}> 禁用订阅 </button> } {!isSubscriptionEnabled && <button className="button" onClick={() => { setModalScene('enableConfirm') setIsOpen(true) }}> 启用订阅 </button> } </div> ) } ReactDOM.render(<App />, document.getElementById('app'));
CSS代码(无需修改)
.app { position: relative; } .button { margin: 20px; } .modalWrapper { position: fixed; top: 0; bottom: 0; left: 0; right: 0; background: #ccc; display: flex; align-items: center; justify-content: center; } .modal { width: 300px; height: 150px; padding: 30px; position: absolute; border: 1px solid teal; background: #fff; }
HTML代码(无需修改)
<div id="app"></div>
内容的提问来源于stack exchange,提问作者Imp3ll
相关产品推荐
相关产品推荐

