验证组件是静态的,而不是在每次渲染时都重新创建。动态重新创建的组件可能会重置状态并触发过多的重新渲染。
规则详情
在其他组件内部定义的组件会在每次渲染时重新创建。React 会将它们视为全新的组件类型,卸载旧组件并挂载新组件,在此过程中销毁所有状态和 DOM 节点。
无效
此规则的错误代码示例:
// ❌ 在组件内部定义组件
function Parent() {
const ChildComponent = () => { // 每次渲染都是新组件!
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
};
return <ChildComponent />; // 状态会在每次渲染时重置
}
// ❌ 动态创建组件
function Parent({type}) {
const Component = type === 'button'
? () => <button>Click</button>
: () => <div>Text</div>;
return <Component />;
}有效
此规则的正确代码示例:
// ✅ 组件位于模块级别
const ButtonComponent = () => <button>Click</button>;
const TextComponent = () => <div>Text</div>;
function Parent({type}) {
const Component = type === 'button'
? ButtonComponent // 引用现有组件
: TextComponent;
return <Component />;
}故障排查
我需要有条件地渲染不同的组件
你可能会在内部定义组件以访问本地状态:
// ❌ 错误:使用内部组件访问父组件状态
function Parent() {
const [theme, setTheme] = useState('light');
function ThemedButton() { // 每次渲染都会重新创建!
return (
<button className={theme}>
点击我
</button>
);
}
return <ThemedButton />;
}改为将数据作为 props 传递:
// ✅ 更好:将 props 传递给静态组件
function ThemedButton({theme}) {
return (
<button className={theme}>
点击我
</button>
);
}
function Parent() {
const [theme, setTheme] = useState('light');
return <ThemedButton theme={theme} />;
}