Effect使用场景
Effect可以让react组件和外部系统同步:如非react组件、网络、DOM。除此之外,不应该使用Effect。
移除不必要的Effect
基于现有的props或state计算得出:const fullName=firstName + lastName;
不用Effect,也能缓存昂贵计算
成千上万个对象计算,才会很耗费时间,可以用useMemo缓存计算结果。
const visibleTodos=useMemo(()=>getFilteredTodos(todos,filter),[todos,filter]);
没有Effect情况下,重置和调整组件的state
props变化重置所有state:
拆分成2个组件,key变化,React将重新创建DOM,并重制Profile组件和它的所有子组件的state。
<Profile
userId={userId}
key={userId}
/>
function Profile({ userId }) {
// ✅ 当 key 变化时,该组件内的 comment 或其他 state 会自动被重置
const [comment, setComment] = useState('');
// ...
}
props变化重置部分state:
function List({ items }) {
const [isReverse, setIsReverse] = useState(false);
const [selection, setSelection] = useState(null);
// 好一些:在渲染期间调整 state
const [prevItems, setPrevItems] = useState(items);
if (items !== prevItems) {
setPrevItems(items);
setSelection(null);
}
// ...
}
计算所需内容,是更好的方法:
function List({ items }) {
const [isReverse, setIsReverse] = useState(false);
const [selectedId, setSelectedId] = useState(null);
// ✅ 非常好:在渲染期间计算所需内容
const selection = items.find(item => item.id === selectedId) ?? null;
// ...
}
在事件处理函数之间共享逻辑
2个按钮单击事件需要做同一件事情,抽取公共方法做此事情。
哪些逻辑应该移动到事件处理函数中
特定交互引起的,保留在事件处理函数中。
如果是屏幕上看到组件时引起的,保留在Effect中。
顶层函数App中根据标识符,来执行一次方法。
let didInit = false;
function App() {
useEffect(() => {
if (!didInit) {
didInit = true;
// ✅ 只在每次应用加载时执行一次
loadDataFromLocalStorage();
checkAuthToken();
}
}, []);
// ...
}
发生的变动通知到父组件
状态提升到父组件中。
订阅外部store