面试题答案
一键面试useEffect 的执行时机
- 首次渲染后执行:当组件第一次渲染到 DOM 中后,
useEffect
中的回调函数会被执行。这使得我们可以在组件挂载后执行一些副作用操作,比如订阅事件、获取数据等。 - 每次更新后执行:在组件后续的更新中(无论是由于 props 变化还是 state 变化导致的更新),
useEffect
的回调函数会再次执行。这保证了在每次数据变化后,相关的副作用操作都能重新执行以保持最新状态。 - 可以控制执行时机:通过传递依赖数组,可以控制
useEffect
回调函数的执行时机。如果依赖数组为空[]
,则useEffect
只会在组件挂载和卸载时执行,不会在每次更新时执行。如果依赖数组包含某些值,只有当这些值发生变化时,useEffect
才会执行。
依赖数组的作用
- 控制副作用的执行频率:如上述提到,通过指定依赖数组,我们可以决定
useEffect
在何时执行。这对于优化性能非常重要,避免不必要的副作用执行。例如,如果useEffect
中执行的是一个昂贵的操作(如 API 调用),通过合理设置依赖数组,可以避免在无关数据变化时重复执行该操作。 - 确保数据一致性:依赖数组中的值代表了
useEffect
中副作用操作所依赖的数据。当这些数据变化时,useEffect
执行以更新相关的状态或 DOM,从而确保应用程序状态和 DOM 与最新的数据保持一致。
实际项目中常见的使用场景
- 数据获取:
在这个例子中,import React, { useState, useEffect } from'react'; const DataFetchingComponent = () => { const [data, setData] = useState(null); useEffect(() => { const fetchData = async () => { const response = await fetch('https://example.com/api/data'); const result = await response.json(); setData(result); }; fetchData(); }, []); return ( <div> {data? <p>{JSON.stringify(data)}</p> : <p>Loading...</p>} </div> ); }; export default DataFetchingComponent;
useEffect
只在组件挂载时执行一次,因为依赖数组为空。它执行数据获取操作,并将获取到的数据设置到 state 中。 - DOM 操作:
这里import React, { useEffect } from'react'; const DOMManipulationComponent = () => { useEffect(() => { const element = document.getElementById('my-element'); if (element) { element.style.color = 'blue'; } return () => { if (element) { element.style.color = 'initial'; } }; }, []); return <div id="my-element">Some text</div>; }; export default DOMManipulationComponent;
useEffect
在组件挂载后获取 DOM 元素并修改其样式。返回的函数是清理函数,在组件卸载时恢复元素的初始样式。 - 事件监听:
import React, { useEffect } from'react'; const EventListenerComponent = () => { const handleScroll = () => { console.log('Window scrolled'); }; useEffect(() => { window.addEventListener('scroll', handleScroll); return () => { window.removeEventListener('scroll', handleScroll); }; }, []); return <div>Scroll the window to see the log</div>; }; export default EventListenerComponent;
useEffect
在组件挂载时添加滚动事件监听器,并在组件卸载时移除监听器,防止内存泄漏。 - 根据 prop 变化进行操作:
当import React, { useEffect } from'react'; const PropDependentComponent = ({ id }) => { useEffect(() => { console.log(`Prop 'id' changed to: ${id}`); // 这里可以执行依赖于 id 的操作,如根据 id 获取特定数据 }, [id]); return <div>{id}</div>; }; export default PropDependentComponent;
id
prop 变化时,useEffect
会执行,从而可以进行依赖于id
的操作。