React点击按钮切换显示两个元素:当前实现是否最优?
更优的重叠区块切换实现方式
你当前的写法是完全可行的,属于React中条件渲染的基础用法。如果想要更简洁、易扩展的实现,可以参考以下几种方案:
方案1:组件映射表
当需要切换的区块数量较多时,用对象映射对应组件,避免重复的block === X判断,扩展性更强:
import * as React from 'react'; import './style.css'; import { FlexContainer } from './styled'; const App = () => { const [activeBlock, setActiveBlock] = React.useState('One'); // 建立区块标识和对应组件的映射 const blockComponents = { One: <div className="FlexContainerColOne"></div>, Two: <div className="FlexContainerColTwo"></div> }; return ( <div> <button onClick={() => setActiveBlock('One')}>Btn One</button> <button onClick={() => setActiveBlock('Two')}>Btn Two</button> <FlexContainer> {/* 直接通过映射表渲染对应组件 */} {blockComponents[activeBlock]} </FlexContainer> </div> ); }; export default App;
方案2:CSS控制显示隐藏(保留DOM)
如果需要保留两个区块的DOM结构(比如要维持区块内的状态、避免重新渲染),可以用CSS的display或visibility控制显示,而非条件渲染:
import * as React from 'react'; import './style.css'; import { FlexContainer } from './styled'; const App = () => { const [activeBlock, setActiveBlock] = React.useState('One'); return ( <div> <button onClick={() => setActiveBlock('One')}>Btn One</button> <button onClick={() => setActiveBlock('Two')}>Btn Two</button> <FlexContainer> <div className="FlexContainerColOne" style={{ display: activeBlock === 'One' ? 'block' : 'none' }} ></div> <div className="FlexContainerColTwo" style={{ display: activeBlock === 'Two' ? 'block' : 'none' }} ></div> </FlexContainer> </div> ); }; export default App;
也可以把样式抽离到CSS类中,比如定义.hidden { display: none; },然后通过动态类名切换:
<div className={`FlexContainerColOne ${activeBlock !== 'One' ? 'hidden' : ''}`} ></div>
方案3:提取可复用按钮组件
如果后续要增加更多切换按钮,提取按钮组件可以减少重复代码:
import * as React from 'react'; import './style.css'; import { FlexContainer } from './styled'; // 复用按钮组件 const BlockToggleBtn = ({ label, targetBlock, onToggle }) => { return <button onClick={() => onToggle(targetBlock)}>{label}</button>; }; const App = () => { const [activeBlock, setActiveBlock] = React.useState('One'); return ( <div> <BlockToggleBtn label="Btn One" targetBlock="One" onToggle={setActiveBlock} /> <BlockToggleBtn label="Btn Two" targetBlock="Two" onToggle={setActiveBlock} /> <FlexContainer> {activeBlock === 'One' && <div className="FlexContainerColOne"></div>} {activeBlock === 'Two' && <div className="FlexContainerColTwo"></div>} </FlexContainer> </div> ); }; export default App;
各方案适用场景
- 方案1:适合需要频繁新增切换区块的场景,代码更简洁易维护
- 方案2:适合区块内有状态需要保留、或不想频繁销毁重建DOM的场景
- 方案3:适合按钮数量较多、样式逻辑一致的场景,减少代码冗余
内容的提问来源于stack exchange,提问作者cdmt
相关产品推荐
相关产品推荐

