掌握React的useEffect:提高开发效率的4个技巧

我们知道 React 的 useEffect 有一些常规用法:
- 在组件挂载时执行一次,能够获取到真实的 dom 元素;
- 组件销毁时执行回调,可以清除和重置数据;
如:
const App = () => {
useEffect(() => {
if (open && values) {
form.setFieldsValue(values);
return () => form.resetFields();
}
}, [open, values]);
};
useEffect的回调会在组件挂载完成时执行一次,后续若依赖项改变,则回调会再次执行。同时在组件卸载时可以清除副作用。基于这个特性,我们实现一些特定的功能。
1. 清除副作用
如定时器、JavaScript 原生事件等,在组件卸载时需要取消定时器和卸载原生事件。
const App = () => {
useEffect(() => {
const timer = setInterval(() => {
console.log(Date.now());
}, 1000);
return () => clearInterval(timer);
}, []);
useEffect(() => {
const listener = () => {
console.log(window.scrollX, window.scrollY);
};
window.addEventListener("scroll", listener, false);
return () => window.removeEventListener("scroll", listenter);
}, []);
};
若没有及时取消,在组件多次渲染时,可能会产生多个定时器或者绑定多个事件。
2. 获取初始值
我在自定义一些稍微复杂的 Form 表单组件时,经常会用到这个功能。
在Ant Design的自定义 Form 表单时,Form 组件会把 value 和 onChange 传给自定义组件内,我们再进行获取。但因为是异步获取数据,form 表单的初始化有延迟,我们并不能马上获取到数据。因此可以监听传入的 value,当获取到 value 后就不再处理该数据。
const InputApp = ({ value: initValue, onChange }) => {
const [value, setValue] = useState(initValue);
const initedRef = useRef(false); // 是否获取到了初始值
useEffect(() => {
if (initedValue && !initedRef.current) {
// 已经有值并且还没初始操作
initedRef.current = true;
setValue(initedValue);
}
}, [initValue]);
};
3. 只监听数据的变化
useEffect()会在组件初始化时执行一次回调函数,然后在依赖项发生变化时,也会执行回调函数。
但是,我们并不希望在组件初始化时执行回调函数,只想监听依赖的变化。我们可以像第 2 小节中那样,用一个标记来表示。
我们认为第一次执行,就是初始时执行;后续是依赖项变化时导致的
因此我们把第一次执行跳过即可。
const App = (props) => {
const firstedRef = useRef(false); // 初始化的回调是否已执行
useEffect(() => {
if (!firstedRef.current) {
firstedRef.current = true;
return;
}
console.log("props changed", props);
}, [props]);
};
4. 获取 DOM 元素
无论是使用 ref 属性和useRef() ,还是原生的 js 方法,获取 DOM 元素,在 useEffect() 中都能保证获取到真实的 DOM 元素。如果是异步获取数据后再渲染 DOM 元素,可以在依赖项中监听对应的数据。
const App = () => {
const domRef = useRef(null);
useEffect(() => {
// 通过 ref 属性 和 useRef() 获取 dom 元素
console.log(domRef.current);
// 通过原生的 js 的方法获取 dom 元素
console.log(document.getElementById("title"));
}, []);
return (
<div ref={domRef}>
<div id="title">前端博客</div>
</div>
);
};
若是通过异步获取数据后,然后再渲染的页面,可以监听相应的数据。
import useSWR from "swr";
const App = () => {
const itemRefs = useRef([]);
const { data } = useSWR("/api", async () => {
const response = await fetch("/api");
return res.json();
});
useEffect(() => {
if (data) {
// 在这里,你可以访问 itemRefs.current 数组,它包含了所有的 DOM 元素
itemRefs.current.forEach((item, index) => {
console.log(`Item ${index}:`, item);
});
}
}, [data]);
return (
<div>
{data?.map((item) => (
<div key={item.id} ref={(ele) => itemRefs.current.push(ele)}></div>
))}
</div>
);
};
5. 总结
在 React 中,使用 useEffect() 可以实现一些特殊的功能。如清除副作用、获取初始值、只监听数据的变化、获取 DOM 元素等。useEffect() 是 React 提供的一个钩子函数,用于在组件渲染后执行副作用操作。副作用操作包括订阅数据源、手动修改 DOM、网络请求等。通过传入一个回调函数给 useEffect(),可在组件的生命周期中执行特定的逻辑。可以传入一个空数组作为第二个参数,仅在组件挂载和卸载时执行一次,用于清除副作用。另外,可以传入一个依赖数组作为第二个参数,仅当依赖项发生变化时才执行回调函数。这样可以优化性能,避免不必要的重复执行。通过 useEffect(),我们可以更加灵活地控制组件的行为,实现各种功能需求。
以上关于掌握React的useEffect:提高开发效率的4个技巧的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » 掌握React的useEffect:提高开发效率的4个技巧

微信
支付宝