做網(wǎng)站可以不買域名和主機(jī)嗎公司網(wǎng)站怎么做推廣
鶴壁市浩天電氣有限公司
2026/01/24 10:47:56
做網(wǎng)站可以不買域名和主機(jī)嗎,公司網(wǎng)站怎么做推廣,杭州設(shè)計(jì)公司老總,營(yíng)銷管理咨詢一、Hooks 進(jìn)階#xff1a;脫離 Class 組件的核心能力
React Hooks 是現(xiàn)代 React 的基石#xff0c;除了 useState/useEffect 基礎(chǔ)用法#xff0c;這些進(jìn)階 Hooks 是處理復(fù)雜邏輯的關(guān)鍵#xff1a;
1. useCallback useMemo#xff1a;性能優(yōu)化#xff08;避免不必要…一、Hooks 進(jìn)階脫離 Class 組件的核心能力React Hooks 是現(xiàn)代 React 的基石除了useState/useEffect基礎(chǔ)用法這些進(jìn)階 Hooks 是處理復(fù)雜邏輯的關(guān)鍵1. useCallback useMemo性能優(yōu)化避免不必要的重渲染/計(jì)算核心場(chǎng)景組件重渲染時(shí)避免函數(shù)/計(jì)算結(jié)果重復(fù)創(chuàng)建導(dǎo)致子組件無(wú)效重渲染。useCallback緩存函數(shù)引用解決“每次渲染函數(shù)重新創(chuàng)建”問(wèn)題useMemo緩存計(jì)算結(jié)果解決“每次渲染重復(fù)計(jì)算”問(wèn)題。示例import { useState, useCallback, useMemo } from react; const Parent () { const [count, setCount] useState(0); const [name, setName] useState(React); // 緩存函數(shù)只有依賴空數(shù)組變化時(shí)函數(shù)引用才會(huì)更新 const handleClick useCallback(() { console.log(點(diǎn)擊了); }, []); // 緩存計(jì)算結(jié)果只有 count 變化時(shí)才重新計(jì)算 const doubleCount useMemo(() { console.log(計(jì)算 doubleCount); return count * 2; }, [count]); return ( div pcount: {count}, double: {doubleCount}/p button onClick{() setCount(count 1)}加1/button button onClick{() setName(Vue)}改名字/button {/* 子組件接收緩存的函數(shù)避免因函數(shù)重新創(chuàng)建導(dǎo)致子組件重渲染 */} Child onClick{handleClick} / /div ); }; // 子組件用 React.memo 配合 useCallback實(shí)現(xiàn)“淺比較props才重渲染” const Child React.memo(({ onClick }) { console.log(子組件渲染); return button onClick{onClick}子組件按鈕/button; });關(guān)鍵useCallback依賴數(shù)組為空 → 函數(shù)永久緩存依賴變化 → 函數(shù)重新創(chuàng)建useMemo不要用于“無(wú)意義的簡(jiǎn)單計(jì)算”比如count 1僅用于“重計(jì)算成本高”的場(chǎng)景比如大數(shù)據(jù)過(guò)濾、復(fù)雜公式必須配合React.memo組件/useMemo計(jì)算才能生效否則單獨(dú)用無(wú)意義。2. useRef跨渲染周期保存數(shù)據(jù) 操作 DOM核心場(chǎng)景保存跨渲染周期的變量不會(huì)因 setState 觸發(fā)重渲染直接操作 DOM 節(jié)點(diǎn)替代 Class 組件的this.refs保存上一次的狀態(tài)/屬性。示例import { useState, useRef, useEffect } from react; const RefDemo () { const [count, setCount] useState(0); // 1. 保存跨渲染周期的變量不會(huì)觸發(fā)重渲染 const countRef useRef(0); // 2. 操作 DOM const inputRef useRef(null); // 3. 保存上一次的 count const prevCountRef useRef(0); useEffect(() { // 每次渲染后更新 prevCountRef prevCountRef.current count; // 操作 DOM聚焦輸入框 inputRef.current.focus(); }, [count]); const handleAdd () { countRef.current 1; // 不會(huì)觸發(fā)重渲染 setCount(count 1); }; return ( div input ref{inputRef} typetext / p當(dāng)前 count: {count}上一次 count: {prevCountRef.current}/p pref 保存的 count: {countRef.current}/p button onClick{handleAdd}加1/button /div ); };3. useContext跨組件通信替代 props 層層傳遞核心場(chǎng)景祖孫組件、非相鄰組件之間共享狀態(tài)比如主題、用戶信息避免“props 鉆取”。示例// 1. 創(chuàng)建 Context const ThemeContext React.createContext(); // 父組件提供 Context 數(shù)據(jù) const Parent () { const [theme, setTheme] useState(light); return ( ThemeContext.Provider value{{ theme, setTheme }} Child / /ThemeContext.Provider ); }; // 子組件無(wú)需接收 props直接消費(fèi) Context const Child () { // 2. 消費(fèi) Context const { theme, setTheme } useContext(ThemeContext); return ( div style{{ background: theme light ? #fff : #333, color: theme light ? #000 : #fff }} p當(dāng)前主題{theme}/p button onClick{() setTheme(theme light ? dark : light)}切換主題/button /div ); };4. useReducer復(fù)雜狀態(tài)邏輯管理替代多個(gè) useState核心場(chǎng)景狀態(tài)邏輯復(fù)雜比如多個(gè)狀態(tài)互相關(guān)聯(lián)、狀態(tài)更新規(guī)則多替代 Redux 做輕量級(jí)狀態(tài)管理。示例import { useReducer } from react; // 1. 定義 reducer 函數(shù)純函數(shù)state action → 新 state const countReducer (state, action) { switch (action.type) { case ADD: return { ...state, count: state.count 1 }; case SUB: return { ...state, count: state.count - 1 }; case RESET: return { ...state, count: 0 }; default: return state; } }; const ReducerDemo () { // 2. 初始化 useReducer(reducer, 初始state) const [state, dispatch] useReducer(countReducer, { count: 0 }); return ( div pcount: {state.count}/p {/* 3. 分發(fā) action觸發(fā) state 更新 */} button onClick{() dispatch({ type: ADD })}加1/button button onClick{() dispatch({ type: SUB })}減1/button button onClick{() dispatch({ type: RESET })}重置/button /div ); };5. useLayoutEffect同步執(zhí)行 DOM 操作比 useEffect 早核心場(chǎng)景需要在 DOM 更新后、瀏覽器繪制前執(zhí)行的操作比如測(cè)量 DOM 尺寸、避免頁(yè)面閃爍。執(zhí)行時(shí)機(jī)useLayoutEffect→ DOM 更新 → 瀏覽器繪制 →useEffect注意內(nèi)部代碼會(huì)阻塞瀏覽器繪制避免做耗時(shí)操作。示例import { useState, useLayoutEffect, useRef } from react; const LayoutEffectDemo () { const [width, setWidth] useState(0); const divRef useRef(null); useLayoutEffect(() { // DOM 更新后立即執(zhí)行測(cè)量 div 寬度無(wú)閃爍 setWidth(divRef.current.offsetWidth); }, []); return div ref{divRef}該元素寬度{width}px/div; };二、自定義 Hooks狀態(tài)邏輯復(fù)用React 高級(jí)用法的核心核心思想將組件中可復(fù)用的邏輯抽離成自定義 Hooks實(shí)現(xiàn)“邏輯復(fù)用代碼解耦”替代 Class 組件的 HOC/Render Props。示例1封裝“防抖”Hook// hooks/useDebounce.js import { useState, useEffect } from react; export const useDebounce (value, delay 500) { const [debouncedValue, setDebouncedValue] useState(value); useEffect(() { // 延遲更新 debouncedValue const timer setTimeout(() { setDebouncedValue(value); }, delay); // 清除定時(shí)器依賴變化時(shí) return () clearTimeout(timer); }, [value, delay]); return debouncedValue; }; // 使用 const Search () { const [input, setInput] useState(); // 防抖后的輸入值500ms 無(wú)變化才更新 const debouncedInput useDebounce(input, 500); // 僅在防抖后的值變化時(shí)請(qǐng)求接口 useEffect(() { if (debouncedInput) { console.log(請(qǐng)求搜索, debouncedInput); } }, [debouncedInput]); return input value{input} onChange{(e) setInput(e.target.value)} placeholder搜索... /; };示例2封裝“請(qǐng)求數(shù)據(jù)”Hook// hooks/useRequest.js import { useState, useEffect } from react; export const useRequest (apiFn, dependencies []) { const [data, setData] useState(null); const [loading, setLoading] useState(true); const [error, setError] useState(null); useEffect(() { const fetchData async () { try { setLoading(true); const res await apiFn(); setData(res); } catch (err) { setError(err); } finally { setLoading(false); } }; fetchData(); }, dependencies); return { data, loading, error }; }; // 使用 const UserList () { // 傳入接口函數(shù)依賴為空 → 僅初始化請(qǐng)求 const { data, loading, error } useRequest(() fetch(/api/users).then(res res.json()), []); if (loading) return div加載中.../div; if (error) return div出錯(cuò)了{(lán)error.message}/div; return ( ul {data?.map(user ( li key{user.id}{user.name}/li ))} /ul ); };三、性能優(yōu)化進(jìn)階1. React.memo組件淺比較避免無(wú)意義重渲染作用對(duì)函數(shù)組件做“淺比較 props”只有 props 變化時(shí)才重渲染注意僅對(duì)比 props 的“淺值”基本類型、引用類型的地址深對(duì)象變化需配合useCallback/useMemo。2. shouldComponentUpdateClass 組件手動(dòng)控制重渲染作用Class 組件中返回true則重渲染false則跳過(guò)替代函數(shù)組件用React.memouseCallback/useMemo。3. React.lazy Suspense代碼分割按需加載組件核心場(chǎng)景減小首屏加載體積只加載當(dāng)前頁(yè)面需要的組件比如路由懶加載。示例import { lazy, Suspense } from react; import { BrowserRouter, Routes, Route } from react-router-dom; // 1. 懶加載組件代碼分割 const Home lazy(() import(./components/Home)); const About lazy(() import(./components/About)); const App () { return ( BrowserRouter {/* 2. Suspense指定加載中的 fallback */} Suspense fallback{div加載中.../div} Routes Route path/ element{Home /} / Route path/about element{About /} / /Routes /Suspense /BrowserRouter ); };4. 不可變數(shù)據(jù)避免意外的狀態(tài)修改React 狀態(tài)更新依賴“不可變數(shù)據(jù)”直接修改原對(duì)象不會(huì)觸發(fā)重渲染推薦用immer簡(jiǎn)化不可變操作import { useState } from react; import { produce } from immer; const ImmerDemo () { const [user, setUser] useState({ name: React, age: 18 }); const handleUpdate () { // 傳統(tǒng)方式手動(dòng)解構(gòu)易出錯(cuò) // setUser({ ...user, age: user.age 1 }); // immer 方式直接“修改”草稿自動(dòng)生成不可變新對(duì)象 setUser(produce(draft { draft.age 1; })); }; return ( div pname: {user.name}, age: {user.age}/p button onClick{handleUpdate}加1歲/button /div ); };四、高級(jí)模式跨場(chǎng)景解決方案1. 錯(cuò)誤邊界Error Boundary捕獲組件內(nèi)的錯(cuò)誤核心場(chǎng)景避免單個(gè)組件報(bào)錯(cuò)導(dǎo)致整個(gè)應(yīng)用崩潰僅支持 Class 組件React 暫未提供 Hooks 版本。示例class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state { hasError: false, error: null }; } // 捕獲子組件的錯(cuò)誤 static getDerivedStateFromError(error) { return { hasError: true, error }; } // 記錄錯(cuò)誤日志 componentDidCatch(error, info) { console.error(錯(cuò)誤信息, error, info); } render() { if (this.state.hasError) { // 自定義錯(cuò)誤提示 return div出錯(cuò)了{(lán)this.state.error?.message}/div; } return this.props.children; } } // 使用包裹可能出錯(cuò)的組件 const App () { return ( ErrorBoundary PotentiallyErrorComponent / /ErrorBoundary ); };2. 端口轉(zhuǎn)發(fā)Portals將組件渲染到 DOM 樹(shù)外核心場(chǎng)景彈窗、模態(tài)框、提示框等避免被父組件的樣式比如overflow: hidden遮擋。示例import { createPortal } from react-dom; const Modal ({ children, visible }) { if (!visible) return null; // 渲染到 body 下的 div而非當(dāng)前組件的 DOM 層級(jí) return createPortal( div style{{ position: fixed, top: 0, left: 0, right: 0, bottom: 0, background: rgba(0,0,0,0.5), display: flex, alignItems: center, justifyContent: center }} div style{{ background: #fff, padding: 20 }}{children}/div /div, document.body // 目標(biāo) DOM 節(jié)點(diǎn) ); }; // 使用 const PortalDemo () { const [visible, setVisible] useState(false); return ( div style{{ height: 200, overflow: hidden, border: 1px solid #eee }} button onClick{() setVisible(true)}打開(kāi)彈窗/button Modal visible{visible}{/* 彈窗內(nèi)容不會(huì)被父組件 overflow 遮擋 */}/Modal /div ); };3. 服務(wù)器組件RSCReact 18 新特性核心場(chǎng)景服務(wù)端渲染組件減少客戶端 JS 體積提升首屏加載速度Next.js 已深度集成。特點(diǎn)組件在服務(wù)端運(yùn)行不依賴瀏覽器 API可直接訪問(wèn)數(shù)據(jù)庫(kù)注意需配合 React 18 服務(wù)端渲染框架Next.js、Remix使用。五、總結(jié)高級(jí)用法的核心價(jià)值React 高級(jí)用法的本質(zhì)是復(fù)用自定義 Hooks 實(shí)現(xiàn)邏輯復(fù)用替代傳統(tǒng)的 HOC/Render Props性能useCallback/useMemo/React.memo減少無(wú)效渲染React.lazy分割代碼解耦useContext/useReducer簡(jiǎn)化狀態(tài)管理避免 props 鉆取和冗余 state兼容錯(cuò)誤邊界、Portals 解決特殊場(chǎng)景的 UI/交互問(wèn)題學(xué)習(xí)建議先掌握基礎(chǔ) HooksuseState/useEffect再逐步學(xué)習(xí)進(jìn)階 Hooks自定義 Hooks 是核心從封裝小邏輯防抖、請(qǐng)求開(kāi)始逐步抽象復(fù)雜邏輯性能優(yōu)化要“按需使用”不要過(guò)度優(yōu)化比如簡(jiǎn)單組件無(wú)需useCallback結(jié)合實(shí)際場(chǎng)景比如表單、列表、彈窗練習(xí)理解“為什么用”比“怎么用”更重要。