先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Web前端全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024c (备注前端)
正文
setError(error);
setData(null);
}
});
}, [url, options]);
};
export default useFetch;
useFetch
返回一个对象,其中包含从URL中获取的数据,如果发生了任何错误,则返回错误。
return { error, data };
最后,向用户表明异步请求的状态通常是一个好做法,比如在呈现结果之前显示 loading。
因此,我们添加第三个 state 变量来跟踪请求的状态。在请求之前,将loading
设置为true
,并在请求之后完成后设置为false
。
const useFetch = (url = ‘’, options = null) => {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [loading, setLoading] = useState(false);
useEffect(() => {
setLoading(true);
fetch(url, options)
.then(res => res.json())
.then(data => {
setData(data);
setError(null);
})
.catch(error => {
setError(error);
setData(null);
})
.finally(() => setLoading(false));
}, [url, options]);
return { error, data };
};
现在,我们可以返回 loading
变量,以便在请求运行时在组件中使用它来呈现一个 loading
,方便用户知道我们正在获取他们所请求的数据。
return { loading, error, data };
在使用 userFetch
之前,我们还有一件事。
我们需要检查使用我们 Hook 的组件是否仍然被挂载,以更新我们的状态变量。否则,会有内存泄漏。
import { useState, useEffect } from ‘react’;
const useFetch = (url = ‘’, options = null) => {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [loading, setLoading] = useState(false);
useEffect(() => {
let isMounted = true;
setLoading(true);
fetch(url, options)
.then(res => res.json())
.then(data => {
if (isMounted) {
setData(data);
setError(null);
}
})
.catch(error => {
if (isMounted) {
setError(error);
setData(null);
}
})
.finally(() => isMounted && setLoading(false));
return () => (isMounted = false);
}, [url, options]);
return { loading, error, data };
};
export default useFetch;
接下就是怎么用了?
我们只需要传递我们想要检索的资源的URL。从那里,我们得到一个对象,我们可以使用它来渲染我们的应用程序。
import useFetch from ‘./useFetch’;
const App = () => {
const { loading, error, data = [] } = useFetch(
‘https://hn.algolia.com/api/v1/search?query=react’
);
if (error) return
Error!
;if (loading) return
Loading…
;return (
{data?.hits?.map(item => (
-
))}
);
};
useEventListener
这个 Hook 负责在组件内部设置和清理事件监听器。
这样,我们就不需要每次添加事件监听器,做重复的工作。
这个函数有几个参数,
eventType
事件类型,listener
监听函数,target
监听对象,options
可选参数。import { useEffect, useRef } from ‘react’;
const useEventListener = (
eventType = ‘’,
listener = () => null,
target = null,
options = null
) => {};
export default useEventListener;
与前一个 Hook 一样,用
useEffect
来添加一个事件监听器。首先,我们需要确保target
是否支持addEventListener
方法。否则,我们什么也不做。import { useEffect, useRef } from ‘react’;
const useEventListener = (
eventType = ‘’,
listener = () => null,
target = null,
options = null
) => {
useEffect(() => {
if (!target?.addEventListener) return;
}, [target]);
};
export default useEventListener;
然后,我们可以添加实际的事件监听器并在卸载函数中删除它。
import { useEffect, useRef } from ‘react’;
const useEventListener = (
eventType = ‘’,
listener = () => null,
target = null,
options = null
) => {
useEffect(() => {
if (!target?.addEventListener) return;
target.addEventListener(eventType, listener, options);
return () => {
target.removeEventListener(eventType, listener, options);
};
}, [eventType, target, options, listener]);
};
export default useEventListener;
实际上,我们也会使用一个引用对象来存储和持久化监听器函数。只有当监听器函数发生变化并在事件监听器方法中使用该引用时,我们才会更新该引用。
import { useEffect, useRef } from ‘react’;
const useEventListener = (
eventType = ‘’,
listener = () => null,
target = null,
options = null
) => {
const savedListener = useRef();
useEffect(() => {
savedListener.current = listener;
}, [listener]);
useEffect(() => {
if (!target?.addEventListener) return;
const eventListener = event => savedListener.current(event);
target.addEventListener(eventType, eventListener, options);
return () => {
target.removeEventListener(eventType, eventListener, options);
};
}, [eventType, target, options]);
};
export default useEventListener;
我们不需要从此 Hook 返回任何内容,因为我们只是侦听事件并运行处理程序函数传入作为参数。
现在,很容易将事件侦听器添加到我们的组件(例如以下组件)中,以检测DOM元素外部的点击。 如果用户单击对话框组件,则在此处关闭对话框组件。
import { useRef } from ‘react’;
import ReactDOM from ‘react-dom’;
import { useEventListener } from ‘./hooks’;
const Dialog = ({ show = false, onClose = () => null }) => {
const dialogRef = useRef();
// Event listener to close dialog on click outside element
useEventListener(
‘mousedown’,
event => {
if (event.defaultPrevented) {
return; // Do nothing if the event was already processed
}
if (dialogRef.current && !dialogRef.current.contains(event.target)) {
console.log(‘Click outside detected -> closing dialog…’);
onClose();
}
},
window
);
return show
? ReactDOM.createPortal(
className=“relative bg-white rounded-md shadow-card max-h-full max-w-screen-sm w-full animate-zoom-in px-6 py-20”
ref={dialogRef}
What’s up{’ '}
YouTube
?
,document.body
-
)
- null;
};
export default Dialog;
useLocalStorage
这个 Hook 主要有两个参数,一个是
key
,一个是value
。import { useState } from ‘react’;
const useLocalStorage = (key = ‘’, initialValue = ‘’) => {};
export default useLocalStorage;
然后,返回一个数组,类似于使用
useState
获得的数组。 因此,此数组将包含有状态值和在将其持久存储在localStorage 中时对其进行更新的函数。首先,我们创建将与 localStorage 同步的React状态变量。
import { useState } from ‘react’;
const useLocalStorage = (key = ‘’, initialValue = ‘’) => {
const [state, setState] = useState(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.log(error);
return initialValue;
}
});
};
export default useLocalStorage;
在这里,我们使用惰性初始化来读取
localStorage
以获取键的值,如果找到该值,则解析该值,否则返回传入的initialValue
。如果在读取
localStorage
时出现错误,我们只记录一个错误并返回初始值。最后,我们需要创建
update
函数来返回它将在localStorage 中存储任何状态的更新,而不是使用useState 返回的默认更新。import { useState } from ‘react’;
const useLocalStorage = (key = ‘’, initialValue = ‘’) => {
const [state, setState] = useState(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
return initialValue;
}
});
const setLocalStorageState = newState => {
try {
const newStateValue =
typeof newState === ‘function’ ? newState(state) : newState;
setState(newStateValue);
window.localStorage.setItem(key, JSON.stringify(newStateValue));
} catch (error) {
console.error(
Unable to store new value for ${key} in localStorage.
);}
};
return [state, setLocalStorageState];
};
export default useLocalStorage;
此函数同时更新React状态和
localStorage
中的相应键/值。 这里,我们还可以支持函数更新,例如常规的useState
hook。最后,我们返回状态值和我们的自定义更新函数。
现在可以使用
useLocalStorage
hook 将组件中的任何数据持久化到localStorage
中。import { useLocalStorage } from ‘./hooks’;
const defaultSettings = {
notifications: ‘weekly’,
};
function App() {
const [appSettings, setAppSettings] = useLocalStorage(
‘app-settings’,
defaultSettings
);
return (
Your application's settings:
<select
value={appSettings.notifications}
onChange={e =>
setAppSettings(settings => ({
…settings,
notifications: e.target.value,
}))
}
className="border border-gray-900 rounded py-2 px-4 "
daily weekly monthly<button
onClick={() => setAppSettings(defaultSettings)}
className=“rounded-md shadow-md py-2 px-6 bg-red-500 text-white uppercase font-medium tracking-wide text-sm leading-8”
Reset settings
);
}
export default App;
useMediaQuery
这个 Hook 帮助我们在功能组件中以编程方式测试和监控媒体查询。这是非常有用的,例如,当你需要渲染不同的UI取决于设备的类型或特定的特征。
我们的 Hook 接受3个参数:
-
首先,对应媒体查询的字符串数组
-
然后,以与前一个数组相同的顺序匹配这些媒体查询的值数组
-
最后,如果没有匹配的媒体查询,则使用默认值
紧跟潮流
大前端和全栈是以后前端的一个趋势,懂后端的前端,懂各端的前端更加具有竞争力,以后可以往这个方向靠拢。
这边整理了一个对标“阿里 50W”年薪企业高级前端工程师成长路线,由于图片太大仅展示一小部分
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
adow-md py-2 px-6 bg-red-500 text-white uppercase font-medium tracking-wide text-sm leading-8"Reset settings
);
}
export default App;
useMediaQuery
这个 Hook 帮助我们在功能组件中以编程方式测试和监控媒体查询。这是非常有用的,例如,当你需要渲染不同的UI取决于设备的类型或特定的特征。
我们的 Hook 接受3个参数:
-
首先,对应媒体查询的字符串数组
-
然后,以与前一个数组相同的顺序匹配这些媒体查询的值数组
-
最后,如果没有匹配的媒体查询,则使用默认值
紧跟潮流
大前端和全栈是以后前端的一个趋势,懂后端的前端,懂各端的前端更加具有竞争力,以后可以往这个方向靠拢。
这边整理了一个对标“阿里 50W”年薪企业高级前端工程师成长路线,由于图片太大仅展示一小部分
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-HO9egEGH-1713230939330)]一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!