React Hooks 深入淺出

目錄

  1. 引言:React Hooks 的革命
  2. 基礎 Hooks
    • useState:狀態管理的新方式
    • useEffect:組件生命周期的替代方案
    • useContext:簡化 Context API
  3. 額外的 Hooks
    • useReducer:復雜狀態邏輯的管理
    • useCallback 與 useMemo:性能優化利器
    • useRef:引用 DOM 和保存變量
  4. 自定義 Hooks:邏輯復用的最佳實踐
  5. Hooks 使用規則與陷阱
  6. 實戰案例:使用 Hooks 重構傳統組件
  7. 總結與展望

引言:React Hooks 的革命

React Hooks 是 React 16.8 版本中引入的特性,它徹底改變了 React 組件的編寫方式。在 Hooks 出現之前,我們需要使用類組件來管理狀態和生命周期,而函數組件則被視為"無狀態組件"。Hooks 的出現使得函數組件也能夠擁有狀態和生命周期功能,從而簡化了組件邏輯,提高了代碼的可讀性和可維護性。

Hooks 解決了 React 中的一些長期存在的問題:

  • 組件之間難以復用狀態邏輯:在 Hooks 之前,我們通常使用高階組件(HOC)或 render props 模式來復用組件邏輯,但這些方法往往導致組件嵌套過深,形成"嵌套地獄"。
  • 復雜組件變得難以理解:生命周期方法中常常混雜著不相關的邏輯,而相關邏輯卻分散在不同的生命周期方法中。
  • 類組件的困惑:類組件需要理解 JavaScript 中 this 的工作方式,這對新手不太友好。

接下來,我們將深入探討 React Hooks 的各個方面,從基礎用法到高級技巧,幫助你全面掌握這一強大特性。

基礎 Hooks

useState:狀態管理的新方式

useState 是最基礎也是最常用的 Hook,它讓函數組件能夠擁有自己的狀態。

import React, { useState } from 'react';function Counter() {// 聲明一個叫 "count" 的 state 變量,初始值為 0const [count, setCount] = useState(0);return (<div><p>你點擊了 {count} 次</p><button onClick={() => setCount(count + 1)}>點擊我</button></div>);
}

useState 返回一個數組,包含兩個元素:當前狀態值和一個更新該狀態的函數。我們使用數組解構來獲取這兩個值。

useState 的高級用法

  1. 函數式更新:當新的狀態依賴于之前的狀態時,推薦使用函數式更新。
// 不推薦
setCount(count + 1);// 推薦
setCount(prevCount => prevCount + 1);
  1. 惰性初始化:如果初始狀態需要通過復雜計算獲得,可以傳遞一個函數給 useState
const [state, setState] = useState(() => {const initialState = someExpensiveComputation(props);return initialState;
});

useEffect:組件生命周期的替代方案

useEffect 讓你在函數組件中執行副作用操作,如數據獲取、訂閱或手動更改 DOM 等。它統一了 componentDidMountcomponentDidUpdatecomponentWillUnmount 這三個生命周期方法。

import React, { useState, useEffect } from 'react';function Example() {const [count, setCount] = useState(0);// 類似于 componentDidMount 和 componentDidUpdateuseEffect(() => {// 更新文檔標題document.title = `你點擊了 ${count} 次`;// 返回一個清理函數,類似于 componentWillUnmountreturn () => {document.title = 'React App';};}, [count]); // 僅在 count 更改時更新return (<div><p>你點擊了 {count} 次</p><button onClick={() => setCount(count + 1)}>點擊我</button></div>);
}

useEffect 的依賴數組

  • 空數組 []:效果只在組件掛載和卸載時執行一次,類似于 componentDidMountcomponentWillUnmount
  • 有依賴項 [a, b]:效果在組件掛載時以及依賴項變化時執行。
  • 無依賴數組:效果在每次渲染后執行。

useContext:簡化 Context API

useContext 讓你可以訂閱 React 的 Context,而不必使用 Context.Consumer 組件。

import React, { useContext } from 'react';// 創建一個 Context
const ThemeContext = React.createContext('light');function ThemedButton() {// 使用 useContext 獲取當前主題const theme = useContext(ThemeContext);return (<button style={{ background: theme === 'dark' ? '#333' : '#fff', color: theme === 'dark' ? '#fff' : '#333' }}>我是一個主題按鈕</button>);
}function App() {return (<ThemeContext.Provider value="dark"><ThemedButton /></ThemeContext.Provider>);
}

useContext 接收一個 Context 對象(由 React.createContext 創建)并返回該 Context 的當前值。當 Provider 更新時,使用該 Context 的組件會重新渲染。

額外的 Hooks

useReducer:復雜狀態邏輯的管理

useReduceruseState 的替代方案,適用于有復雜狀態邏輯的場景,特別是當下一個狀態依賴于之前的狀態時。

import React, { useReducer } from 'react';// 定義 reducer 函數
function reducer(state, action) {switch (action.type) {case 'increment':return { count: state.count + 1 };case 'decrement':return { count: state.count - 1 };default:throw new Error();}
}function Counter() {// 使用 useReducerconst [state, dispatch] = useReducer(reducer, { count: 0 });return (<div>Count: {state.count}<button onClick={() => dispatch({ type: 'increment' })}>+</button><button onClick={() => dispatch({ type: 'decrement' })}>-</button></div>);
}

useReducer 返回當前狀態和 dispatch 函數。dispatch 函數用于觸發狀態更新,它接收一個 action 對象,通常包含 type 屬性和可選的 payload。

useCallback 與 useMemo:性能優化利器

這兩個 Hooks 主要用于性能優化,避免不必要的計算和渲染。

useCallback:返回一個記憶化的回調函數,只有當依賴項變化時才會更新。

import React, { useState, useCallback } from 'react';function ParentComponent() {const [count, setCount] = useState(0);// 使用 useCallback 記憶化回調函數const handleClick = useCallback(() => {console.log(`Button clicked, count: ${count}`);}, [count]); // 只有當 count 變化時,handleClick 才會更新return (<div><ChildComponent onClick={handleClick} /><button onClick={() => setCount(count + 1)}>Increment</button></div>);
}// 使用 React.memo 優化子組件
const ChildComponent = React.memo(({ onClick }) => {console.log('ChildComponent rendered');return <button onClick={onClick}>Click me</button>;
});

useMemo:返回一個記憶化的值,只有當依賴項變化時才重新計算。

import React, { useState, useMemo } from 'react';function ExpensiveCalculation({ a, b }) {// 使用 useMemo 記憶化計算結果const result = useMemo(() => {console.log('Computing result...');// 假設這是一個耗時的計算return a * b;}, [a, b]); // 只有當 a 或 b 變化時,才重新計算return <div>Result: {result}</div>;
}

useRef:引用 DOM 和保存變量

useRef 返回一個可變的 ref 對象,其 .current 屬性被初始化為傳入的參數。返回的 ref 對象在組件的整個生命周期內保持不變。

引用 DOM 元素

import React, { useRef, useEffect } from 'react';function TextInputWithFocusButton() {// 創建一個 refconst inputRef = useRef(null);// 點擊按鈕時聚焦輸入框const focusInput = () => {inputRef.current.focus();};return (<div><input ref={inputRef} type="text" /><button onClick={focusInput}>聚焦輸入框</button></div>);
}

保存變量

import React, { useState, useRef, useEffect } from 'react';function Timer() {const [count, setCount] = useState(0);// 使用 useRef 保存 interval IDconst intervalRef = useRef(null);useEffect(() => {// 設置定時器intervalRef.current = setInterval(() => {setCount(c => c + 1);}, 1000);// 清理定時器return () => {clearInterval(intervalRef.current);};}, []); // 空依賴數組,只在掛載和卸載時執行// 停止計時器const stopTimer = () => {clearInterval(intervalRef.current);};return (<div><p>計數: {count}</p><button onClick={stopTimer}>停止</button></div>);
}

useState 不同,useRef.current 屬性變化不會觸發組件重新渲染。

自定義 Hooks:邏輯復用的最佳實踐

自定義 Hooks 是 React Hooks 最強大的特性之一,它允許你將組件邏輯提取到可重用的函數中。自定義 Hook 是一個以 “use” 開頭的 JavaScript 函數,可以調用其他 Hooks。

示例:創建一個 useLocalStorage Hook

import { useState, useEffect } from 'react';// 自定義 Hook:使用 localStorage 持久化狀態
function useLocalStorage(key, initialValue) {// 初始化狀態const [storedValue, setStoredValue] = useState(() => {try {// 嘗試從 localStorage 獲取值const item = window.localStorage.getItem(key);// 如果存在則解析并返回,否則返回初始值return item ? JSON.parse(item) : initialValue;} catch (error) {console.log(error);return initialValue;}});// 更新 localStorage 的函數const setValue = value => {try {// 允許值是一個函數,類似于 useStateconst valueToStore = value instanceof Function ? value(storedValue) : value;// 保存到 statesetStoredValue(valueToStore);// 保存到 localStoragewindow.localStorage.setItem(key, JSON.stringify(valueToStore));} catch (error) {console.log(error);}};return [storedValue, setValue];
}// 使用自定義 Hook
function App() {const [name, setName] = useLocalStorage('name', 'Bob');return (<div><inputtype="text"value={name}onChange={e => setName(e.target.value)}/></div>);
}

示例:創建一個 useWindowSize Hook

import { useState, useEffect } from 'react';// 自定義 Hook:獲取窗口尺寸
function useWindowSize() {// 初始化狀態const [windowSize, setWindowSize] = useState({width: undefined,height: undefined,});useEffect(() => {// 處理窗口大小變化的函數function handleResize() {setWindowSize({width: window.innerWidth,height: window.innerHeight,});}// 添加事件監聽器window.addEventListener('resize', handleResize);// 初始調用一次以設置初始值handleResize();// 清理函數return () => window.removeEventListener('resize', handleResize);}, []); // 空依賴數組,只在掛載和卸載時執行return windowSize;
}// 使用自定義 Hook
function ResponsiveComponent() {const size = useWindowSize();return (<div>{size.width < 768 ? (<p>在小屏幕上顯示</p>) : (<p>在大屏幕上顯示</p>)}</div>);
}

Hooks 使用規則與陷阱

使用 Hooks 時,必須遵循兩條重要規則:

  1. 只在最頂層使用 Hooks:不要在循環、條件或嵌套函數中調用 Hooks,確保 Hooks 在每次組件渲染時都以相同的順序被調用。
// ? 錯誤:在條件語句中使用 Hook
function Form() {const [name, setName] = useState('Mary');if (name !== '') {useEffect(() => {localStorage.setItem('name', name);});}// ...
}// ? 正確:將條件放在 Hook 內部
function Form() {const [name, setName] = useState('Mary');useEffect(() => {if (name !== '') {localStorage.setItem('name', name);}});// ...
}
  1. 只在 React 函數組件或自定義 Hooks 中調用 Hooks:不要在普通的 JavaScript 函數中調用 Hooks。

常見陷阱與解決方案

  1. 依賴數組遺漏
// ? 錯誤:依賴數組遺漏了 count
function Counter({ count }) {useEffect(() => {document.title = `Count: ${count}`;}, []); // 依賴數組為空,但使用了 count// ...
}// ? 正確:添加所有依賴項
function Counter({ count }) {useEffect(() => {document.title = `Count: ${count}`;}, [count]); // 正確添加了 count 作為依賴項// ...
}
  1. 閉包陷阱
// ? 問題:使用過時的狀態值
function Counter() {const [count, setCount] = useState(0);useEffect(() => {const timer = setInterval(() => {console.log(`Current count: ${count}`);setCount(count + 1); // 這里的 count 是閉包捕獲的初始值}, 1000);return () => clearInterval(timer);}, []); // 依賴數組為空,導致 count 始終為初始值 0// ...
}// ? 解決方案:使用函數式更新
function Counter() {const [count, setCount] = useState(0);useEffect(() => {const timer = setInterval(() => {setCount(prevCount => prevCount + 1); // 使用函數式更新獲取最新狀態}, 1000);return () => clearInterval(timer);}, []); // 現在可以安全地使用空依賴數組// ...
}
  1. 過度依賴 useEffect
// ? 不必要的 useEffect
function Form() {const [firstName, setFirstName] = useState('');const [lastName, setLastName] = useState('');// 不必要的 useEffect,可以直接計算const [fullName, setFullName] = useState('');useEffect(() => {setFullName(`${firstName} ${lastName}`);}, [firstName, lastName]);// ...
}// ? 更好的方式:直接計算派生狀態
function Form() {const [firstName, setFirstName] = useState('');const [lastName, setLastName] = useState('');// 直接計算派生值,無需額外的狀態和 useEffectconst fullName = `${firstName} ${lastName}`;// ...
}

實戰案例:使用 Hooks 重構傳統組件

讓我們通過一個實際例子,展示如何將類組件重構為使用 Hooks 的函數組件。

原始類組件

import React, { Component } from 'react';class UserProfile extends Component {constructor(props) {super(props);this.state = {user: null,loading: true,error: null};}componentDidMount() {this.fetchUserData();}componentDidUpdate(prevProps) {if (prevProps.userId !== this.props.userId) {this.fetchUserData();}}fetchUserData = async () => {this.setState({ loading: true });try {const response = await fetch(`https://api.example.com/users/${this.props.userId}`);const data = await response.json();this.setState({ user: data, loading: false });} catch (error) {this.setState({ error, loading: false });}};render() {const { user, loading, error } = this.state;if (loading) return <div>Loading...</div>;if (error) return <div>Error: {error.message}</div>;if (!user) return <div>No user data</div>;return (<div><h1>{user.name}</h1><p>Email: {user.email}</p><p>Phone: {user.phone}</p></div>);}
}

使用 Hooks 重構后的函數組件

import React, { useState, useEffect } from 'react';function UserProfile({ userId }) {const [user, setUser] = useState(null);const [loading, setLoading] = useState(true);const [error, setError] = useState(null);useEffect(() => {async function fetchUserData() {setLoading(true);try {const response = await fetch(`https://api.example.com/users/${userId}`);const data = await response.json();setUser(data);setLoading(false);} catch (error) {setError(error);setLoading(false);}}fetchUserData();}, [userId]); // 依賴項數組,只有當 userId 變化時才重新獲取數據if (loading) return <div>Loading...</div>;if (error) return <div>Error: {error.message}</div>;if (!user) return <div>No user data</div>;return (<div><h1>{user.name}</h1><p>Email: {user.email}</p><p>Phone: {user.phone}</p></div>);
}

進一步優化:提取自定義 Hook

import React, { useState, useEffect } from 'react';// 自定義 Hook:獲取用戶數據
function useUserData(userId) {const [user, setUser] = useState(null);const [loading, setLoading] = useState(true);const [error, setError] = useState(null);useEffect(() => {async function fetchUserData() {setLoading(true);try {const response = await fetch(`https://api.example.com/users/${userId}`);const data = await response.json();setUser(data);setLoading(false);} catch (error) {setError(error);setLoading(false);}}fetchUserData();}, [userId]);return { user, loading, error };
}// 使用自定義 Hook 的組件
function UserProfile({ userId }) {const { user, loading, error } = useUserData(userId);if (loading) return <div>Loading...</div>;if (error) return <div>Error: {error.message}</div>;if (!user) return <div>No user data</div>;return (<div><h1>{user.name}</h1><p>Email: {user.email}</p><p>Phone: {user.phone}</p></div>);
}

通過這個例子,我們可以看到 Hooks 帶來的幾個明顯優勢:

  1. 代碼更簡潔:函數組件比類組件代碼量少,更易于閱讀和理解。
  2. 關注點分離:通過自定義 Hook,我們可以將數據獲取邏輯與 UI 渲染邏輯分離。
  3. 邏輯復用:自定義 Hook 可以在多個組件之間復用,而不需要使用 HOC 或 render props。

總結與展望

React Hooks 徹底改變了 React 組件的編寫方式,使函數組件成為了 React 開發的主流。通過本文,我們深入探討了 React Hooks 的基礎知識、高級用法、常見陷阱以及最佳實踐。

Hooks 的優勢總結:

  1. 簡化組件邏輯:使用 Hooks,我們可以將相關的邏輯放在一起,而不是分散在不同的生命周期方法中。
  2. 促進邏輯復用:自定義 Hooks 提供了一種比 HOC 和 render props 更簡潔的邏輯復用方式。
  3. 更好的類型推斷:在 TypeScript 中,Hooks 比類組件有更好的類型推斷。
  4. 減少代碼量:函數組件通常比等效的類組件代碼量少。
  5. 更容易測試:純函數更容易測試,Hooks 使得編寫純函數組件變得更加容易。

隨著 React 的發展,Hooks 生態系統也在不斷壯大。React 團隊還在探索更多的 Hooks,如 useTransitionuseDeferredValue,以解決并發模式下的性能問題。同時,社區也開發了大量的第三方 Hooks 庫,如 react-useuse-http 等,進一步擴展了 Hooks 的能力。


參考資料:

  1. React 官方文檔 - Hooks 介紹
  2. React Hooks 完全指南
  3. 使用 React Hooks 的常見錯誤
  4. 深入理解 React useEffect

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/80349.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/80349.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/80349.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【應急響應】- 日志流量如何分析?

【應急響應】- 日志流量如何下手&#xff1f;https://mp.weixin.qq.com/s/dKl8ZLZ0wjuqUezKo4eUSQ

stm32 debug卡在0x1FFFxxxx

自己畫的一個四軸飛機電路板&#xff0c;之前還能debug&#xff0c;改了一下mos管兩端的電阻&#xff0c;還能正常下載&#xff0c;藍牙接收也正常&#xff0c;但是debug出問題了&#xff0c;剛下載就自動運行&#xff0c;然后程序就在0x1FFFxxxx附近循環運行&#xff0c;這一塊…

java-----------------多態

多態&#xff0c;當前指的是 java 所呈現出來的一個對象 多態 定義 多態是指同一個行為具有多個不同表現形式或形態的能力。在面向對象編程中&#xff0c;多態通過方法重載和方法重寫來實現。 強弱類型語言 javascript 或者python 是弱類型語言 C 語言&#xff0c;或者 C…

Java 23種設計模式 - 結構型模式7種

Java 23種設計模式 - 結構型模式7種 1 適配器模式 適配器模式把一個類的接口變換成客戶端所期待的另一種接口&#xff0c;從而使原本因接口不匹配而無法在一起工作的兩個類能夠在一起工作。 優點 將目標類和適配者類解耦增加了類的透明性和復用性&#xff0c;將具體的實現封…

Git clone時出現SSL certificate problem unable to get local issuer certificate

正確解決方法 git config --global http.sslVerify false錯誤解決方法&#xff1a;&#xff08;主要是看錯了嘿嘿&#xff0c;但是如果是 OpenSSL SSL_read: Connection was reset, errno 10054 Failed to connect to github.com port 443: Timed out 原…

DevExpressWinForms-AlertControl-使用教程

文章目錄 AlertControl-使用教程一、將 AlertControl 添加到 Form二、編輯 AlertControl 的 HtmlTemplateHTML Template Editor介紹編輯HTML Template 三、使用AlertControl彈出AlertAlert中的按鈕事件獲取 Alert 標題等信息向Alert傳遞參數 總結源碼 AlertControl-使用教程 一…

制作項目進度表常用的 8 款項目管理工具分享

在數字化管理和高效協作的今天&#xff0c;項目進度表軟件已經成為企業管理不可或缺的工具。無論是中小型企業還是大型機構&#xff0c;都需要通過精準的項目計劃和實時的進度跟蹤來確保業務目標的順利達成。這篇文章將聚焦項目進度表軟件&#xff0c;深入探討市場上8款主流產品…

SecureCRT網絡穿透/代理

場景 公司的辦公VPN軟件只有Windows系統版本&#xff0c;沒有Macos系統版本&#xff0c;而日常開發過程中需要先登錄VPN后&#xff0c;然后才能登錄應用服務器。 目的&#xff1a;Macos系統在使用SecureCRT時&#xff0c;登錄服務器&#xff0c;需要走Parallels Desktop進行網絡…

【計算機網絡-傳輸層】傳輸層協議-TCP核心機制與可靠性保障

&#x1f4da; 博主的專欄 &#x1f427; Linux | &#x1f5a5;? C | &#x1f4ca; 數據結構 | &#x1f4a1;C 算法 | &#x1f152; C 語言 | &#x1f310; 計算機網絡 上篇文章&#xff1a;傳輸層協議-UDP 下篇文章&#xff1a; 網絡層 我們的講解順序是&…

OpenMagnetic的介紹與使用

1. Background OM&#xff08;OpenMagnetic&#xff09;OpenMagnetics&#xff0c;能涵蓋氣隙磁阻&#xff0c;磁導率&#xff0c;鐵芯損耗、磁滯損耗、渦流電流損耗、渦流效應、漏感、溫升的計算與仿真[1]。 鐵損計算模型&#xff1a;改進的Steinmetz方程[2] 氣隙阻抗計算&…

【JVM】從零開始深度解析JVM

本篇博客給大家帶來的是JVM的知識點, 重點在類加載和垃圾回收機制上. &#x1f40e;文章專欄: JavaEE初階 &#x1f680;若有問題 評論區見 ? 歡迎大家點贊 評論 收藏 分享 如果你不知道分享給誰,那就分享給薯條. 你們的支持是我不斷創作的動力 . 王子,公主請閱&#x1f680; …

字符串---Spring字符串基本處理

一、String類的特性 不可變性 String對象一旦創建&#xff0c;內容不可更改&#xff0c;任何修改操作都會生成新對象。字符串常量池 字符串字面量&#xff08;如"abc"&#xff09;直接存儲在常量池中&#xff0c;重復字面量共享同一內存地址。創建方式 雖然都是字符…

26考研——中央處理器_CPU 的功能和基本結構(5)

408答疑 文章目錄 一、CPU 的功能和基本結構CPU 的功能CPU 的基本結構運算器控制器 CPU 的寄存器運算器中的寄存器控制器中的寄存器 八、參考資料鮑魚科技課件26王道考研書 九、總結 一、CPU 的功能和基本結構 CPU 的功能 中央處理器&#xff08;CPU&#xff09;由運算器和控…

傳統數據展示 vs 可視化:誰更打動人心?

數據&#xff0c;每天都在我們身邊流動&#xff1a;從你手機里的健康步數&#xff0c;到企業財報中的營收增長&#xff0c;再到國家發布的經濟指標。但問題是——你怎么“看”這些數據&#xff1f; 過去&#xff0c;我們習慣用表格、文字和報告來展示數據&#xff0c;這種方式…

Base64 編碼原理詳細解析

Base64 編碼是一種常見的數據編碼方式&#xff0c;它將二進制數據轉化為可打印的 ASCII 字符串。Base64 編碼廣泛應用于電子郵件、URL 編碼、HTTP 請求和響應中等場景。它的核心作用是讓二進制數據可以通過僅支持文本的協議或媒介進行傳輸。本文將更深入地探討 Base64 編碼的原…

一周學會Pandas2 Python數據處理與分析-Pandas2數據排序操作

鋒哥原創的Pandas2 Python數據處理與分析 視頻教程&#xff1a; 2025版 Pandas2 Python數據處理與分析 視頻教程(無廢話版) 玩命更新中~_嗶哩嗶哩_bilibili Pandas 2提供了多種靈活的數據排序方法&#xff0c;主要針對 DataFrame 和 Series 對象。 1. 按值排序&#xff1a;s…

計算機二級(C語言)已過

非線性結構&#xff1a;樹、圖 鏈表和隊列的結構特性不一樣&#xff0c;鏈表可以在任何位置插入、刪除&#xff0c;而隊列只能在隊尾入隊、隊頭出隊 對長度為n的線性表排序、在最壞情況下時間復雜度&#xff0c;二分查找為O(log2n)&#xff0c;順序查找為O(n)&#xff0c;哈希查…

Windows Server 2025開啟GPU分區(GPU-P)部署DoraCloud云桌面

本文描述在ShareStation工作站虛擬化方案的部署過程。 將服務器上部署 Windows Server、DoraCloud&#xff0c;并創建帶有vGPU的虛擬桌面。 GPU分區技術介紹 GPU-P&#xff08;GPU Partitioning&#xff09; 是微軟在 Windows 虛擬化平臺&#xff08;如 Hyper-V&#xff09;中…

Android RxJava框架分析:它的執行流程是如何的?它的線程是如何切換的?如何自定義RxJava操作符?

目錄 RxJava是什么&#xff1f;為什么使用。RxJava是如何使用的呢&#xff1f;RxJava如何和Retrofit一起使用。RxJava源碼分析。 &#xff08;1&#xff09;他執行流程是如何的。&#xff08;2&#xff09;map&#xff08;3&#xff09;線程的切換。 如何自定義RxJava操作符…

QT的初始代碼解讀及其布局和彈簧

this指的是真正的當前正在顯示的窗口 main函數&#xff1a; Widget w是生成了一個主窗口&#xff0c;QT Designer是在這個主窗口里塞組件 w.show()用來展示這個主窗口 頭文件&#xff1a; namespace Ui{class Widget;}中的class Widget和下面的class Widget不是一個東西 Ui…