在 React 中,保持组件的纯粹性意味着组件的行为应始终遵循以下原则:相同的输入(props/state)一定会产生相同的输出(UI),并且不会产生副作用(如直接修改外部变量、操作 DOM、发起网络请求等)。这是 React 的核心设计理念之一,确保组件可预测、可维护且易于调试。
保持纯粹性的核心原则
-
输入决定输出
组件应该像一个纯函数:给定相同的props和state,永远返回相同的 JSX。// ✅ 纯组件:输出完全由 props 决定 function PureComponent({ name }) { return <div>{name}</div>; } // ❌ 非纯组件:输出可能随时间变化 function ImpureComponent({ name }) { return <div>{name + Math.random()}</div>; // 随机值破坏纯粹性 } -
不产生副作用
副作用(如网络请求、修改全局变量、操作 DOM)应放在useEffect、事件处理函数或生命周期方法中,而不是在渲染过程中直接执行。// ✅ 副作用放在 useEffect 中 function Component() { useEffect(() => { fetchData(); // 副作用在渲染后执行 }, []); return <div>Hello</div>; } // ❌ 渲染过程中直接执行副作用 function ImpureComponent() { fetchData(); // 直接发起请求,破坏纯粹性 return <div>Hello</div>; } -
不直接修改状态或 props
React 要求状态更新必须是不可变的(Immutable),直接修改state或props会破坏组件行为的一致性。function Component() { const [list, setList] = useState([1, 2, 3]); // ✅ 正确:通过创建新数组更新状态 const addItem = () => { setList([...list, 4]); }; // ❌ 错误:直接修改原数组 const badAddItem = () => { list.push(4); // 直接修改 state! setList(list); }; return <button onClick={addItem}>Add</button>; } -
幂等性
多次调用组件渲染函数不应改变外部状态。// ✅ 幂等:多次渲染不会改变外部变量 function PureComponent() { return <div>Hello</div>; } // ❌ 非幂等:每次渲染修改全局变量 let count = 0; function ImpureComponent() { count++; // 破坏幂等性 return <div>Rendered {count} times</div>; }
常见破坏纯粹性的场景
1. 在渲染过程中修改外部变量
let externalValue = 0;
function ImpureComponent() {
externalValue++; // 直接修改外部变量
return <div>{externalValue}</div>;
}
2. 直接操作 DOM
function ImpureComponent() {
// ❌ 渲染过程中直接操作 DOM
document.title = "New Title";
return <div>Hello</div>;
}
3. 依赖外部可变数据
let globalData = { value: 10 };
function ImpureComponent() {
// ❌ 依赖外部可变数据,输出不可预测
return <div>{globalData.value}</div>;
}
4. 在渲染中发起网络请求
function ImpureComponent() {
// ❌ 直接在渲染中发起请求
fetch("/api/data").then((res) => { /* ... */ });
return <div>Loading...</div>;
}
如何保持纯粹性?
-
使用
React.memo或PureComponent
通过记忆化(Memoization)避免不必要的重新渲染,但前提是组件本身是纯的。const MemoizedComponent = React.memo(function PureComponent({ data }) { return <div>{data}</div>; }); -
将副作用隔离到
useEffect或事件处理函数function Component() { const [data, setData] = useState(null); useEffect(() => { // ✅ 副作用在 useEffect 中执行 fetch("/api/data").then((res) => setData(res)); }, []); return <div>{data}</div>; } -
遵循不可变性更新状态
使用展开运算符(...)、map、filter等方式创建新对象/数组。const [user, setUser] = useState({ name: "Alice", age: 20 }); // ✅ 正确:创建新对象 setUser({ ...user, age: 21 }); // ❌ 错误:直接修改原对象 user.age = 21; setUser(user); -
使用严格模式(StrictMode)检测问题
React 的StrictMode会故意多次调用渲染函数,帮助发现不纯的代码。ReactDOM.createRoot(document.getElementById('root')).render( <React.StrictMode> <App /> </React.StrictMode> );
总结
保持组件的纯粹性意味着:
- 渲染结果仅由
props和state决定。 - 避免在渲染过程中产生副作用。
- 状态更新遵循不可变性原则。
这确保了组件的可预测性、可测试性,并充分利用 React 的性能优化机制(如虚拟 DOM 比对)。
1387

被折叠的 条评论
为什么被折叠?



