🎯 条件渲染写法解析
📝 语法含义
{modalVisible && (
<NewModal
// props...
/>
)}
这是 短路求值(Short-circuit evaluation) 的JavaScript特性:
- 当
modalVisible为true时,执行右侧组件渲染 - 当
modalVisible为false时,右侧不执行,返回false(React会忽略)
🔄 等价写法对比
// 方式1: 短路求值 (推荐)
{modalVisible && <Modal />}
// 方式2: 三元运算符
{modalVisible ? <Modal /> : null}
// 方式3: if语句
{(() => {
if (modalVisible) {
return <Modal />;
}
return null;
})()}
// 方式4: 始终渲染,用CSS控制 (不推荐)
<Modal style={{ display: modalVisible ? 'block' : 'none' }} />
🚀 为什么要这样写?核心优势
✅ 1. 性能优化 - 避免不必要的DOM创建
// ❌ 不好的写法 - 组件始终存在
<Modal visible={modalVisible} />
// ✅ 好的写法 - 组件按需创建
{modalVisible && <Modal />}
✅ 2. 内存优化 - 组件完全卸载
// 当 modalVisible = false 时:
// - 组件实例被销毁
// - 占用的内存被释放
// - 事件监听器被清理
// - 定时器被清除
✅ 3. 生命周期控制
function Modal() {
useEffect(() => {
console.log('Modal mounted'); // 只在需要时执行
return () => {
console.log('Modal unmounted'); // 关闭时清理
};
}, []);
return <div>Modal Content</div>;
}
🔄 React组件生命周期详解
📊 1. 函数组件生命周期
function MyComponent() {
// 🔵 组件渲染阶段
console.log('1. 函数组件执行');
// 🟢 组件挂载后
useEffect(() => {
console.log('2. 组件挂载完成 (componentDidMount)');
// 🔴 组件卸载前
return () => {
console.log('4. 组件卸载 (componentWillUnmount)');
};
}, []); // 空依赖数组
// 🟡 组件更新后
useEffect(() => {
console.log('3. 组件更新完成 (componentDidUpdate)');
}); // 无依赖数组,每次渲染都执行
return <div>组件内容</div>;
}
📊 2. 类组件生命周期对比
class MyComponent extends React.Component {
// 🔵 挂载阶段
constructor(props) {
super(props);
console.log('1. constructor');
}
componentDidMount() {
console.log('2. componentDidMount');
}
// 🟡 更新阶段
componentDidUpdate() {
console.log('3. componentDidUpdate');
}
// 🔴 卸载阶段
componentWillUnmount() {
console.log('4. componentWillUnmount');
}
render() {
console.log('render');
return <div>组件内容</div>;
}
}
🎨 条件渲染的具体场景对比
🔥 场景1: 弹窗组件
// ❌ 始终渲染方式
function App() {
const [modalVisible, setModalVisible] = useState(false);
return (
<div>
<button onClick={() => setModalVisible(true)}>打开弹窗</button>
<Modal
visible={modalVisible}
onClose={() => setModalVisible(false)}
/> {/* 组件始终存在DOM中 */}
</div>
);
}
// ✅ 条件渲染方式
function App() {
const [modalVisible, setModalVisible] = useState(false);
return (
<div>
<button onClick={() => setModalVisible(true)}>打开弹窗</button>
{modalVisible && (
<Modal onClose={() => setModalVisible(false)} />
)} {/* 组件按需创建/销毁 */}
</div>
);
}
📈 性能影响对比
// ❌ 始终渲染的问题
function ExpensiveModal() {
useEffect(() => {
// 这些操作始终执行,即使不可见
const timer = setInterval(() => {
console.log('定时任务执行');
}, 1000);
window.addEventListener('resize', handleResize);
return () => {
clearInterval(timer);
window.removeEventListener('resize', handleResize);
};
}, []);
return <div>复杂的弹窗内容</div>;
}
// ✅ 条件渲染的优势
function App() {
return (
<div>
{/* 只有在需要时才创建ExpensiveModal */}
{showModal && <ExpensiveModal />}
</div>
);
}
🛠️ 组件性能优化策略
🎯 1. 条件渲染优化
// ✅ 基础条件渲染
{show && <Component />}
// ✅ 复杂条件渲染
{isLoggedIn && hasPermission && <AdminPanel />}
// ✅ 使用 useMemo 优化复杂计算
const shouldShowComponent = useMemo(() => {
return complexCalculation(data);
}, [data]);
{shouldShowComponent && <ExpensiveComponent />}
🎯 2. 组件懒加载
// ✅ React.lazy + Suspense
const LazyModal = React.lazy(() => import('./Modal'));
function App() {
const [showModal, setShowModal] = useState(false);
return (
<div>
{showModal && (
<Suspense fallback={<div>Loading...</div>}>
<LazyModal />
</Suspense>
)}
</div>
);
}
🎯 3. 状态提升优化
// ❌ 每个组件都管理自己的状态
function TodoItem({ todo }) {
const [isEditing, setIsEditing] = useState(false);
return (
<div>
{isEditing && <EditForm />} {/* 每个item都可能渲染EditForm */}
</div>
);
}
// ✅ 状态提升,全局只有一个编辑表单
function TodoList({ todos }) {
const [editingId, setEditingId] = useState(null);
return (
<div>
{todos.map(todo => (
<TodoItem key={todo.id} todo={todo} />
))}
{editingId && <EditForm todoId={editingId} />} {/* 全局唯一 */}
</div>
);
}
🎯 4. 使用 Portal 优化弹窗
import { createPortal } from 'react-dom';
function Modal({ children, onClose }) {
useEffect(() => {
const handleEscape = (e) => {
if (e.key === 'Escape') onClose();
};
document.addEventListener('keydown', handleEscape);
document.body.style.overflow = 'hidden'; // 防止滚动
return () => {
document.removeEventListener('keydown', handleEscape);
document.body.style.overflow = 'unset';
};
}, [onClose]);
// 渲染到body而不是父组件中
return createPortal(
<div className="modal-overlay" onClick={onClose}>
<div className="modal-content" onClick={e => e.stopPropagation()}>
{children}
</div>
</div>,
document.body
);
}
// 使用
{showModal && (
<Modal onClose={() => setShowModal(false)}>
<div>弹窗内容</div>
</Modal>
)}
📊 不同场景的最佳实践
🔥 弹窗/模态框
// ✅ 推荐:条件渲染
{modalVisible && <Modal />}
🎨 显示/隐藏元素
// ✅ 简单显隐:CSS控制
<div style={{ display: isVisible ? 'block' : 'none' }}>
// ✅ 复杂组件:条件渲染
{isVisible && <ComplexComponent />}
📱 路由组件
// ✅ React Router已经做了条件渲染优化
<Routes>
<Route path="/home" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
💡 总结
条件渲染 {condition && <Component />} 的核心价值在于:
- 性能优化:避免不必要的组件创建和渲染
- 内存管理:组件完全卸载,释放资源
- 生命周期控制:精确控制组件的创建和销毁时机
- 代码简洁:语法简单,语义清晰
这种写法特别适合重型组件、弹窗、复杂表单等场景,是React开发中的重要优化手段!