作用
配合函數式編程,保證在不產生類的時候完成一個整體的組件
常用組件
- useState
- useContext
- useReducer
- useEffect
- useMemo
- useCallback
前三個值為自變量
后三者為因變量
前三者相當于其他編程函數的變量聲明,而后三者相當于對變量進行了(if now != previous)
的包裝,執行函數
useState
適用于:簡單邏輯狀態管理
//創建
const [state, setState] = useState(defaultState)//直接修改
setState(nextState);
// 函數修改,會接收到一個參數是原先 state 的值,該函數的返回值將作為更新后 state 的值
setState(preState => nextState);
useReducer
用于處理更復雜的狀態邏輯。相比于 useState,它更適合用于處理涉及多個子值的狀態,或者下一個狀態依賴于之前的狀態的情況
// 定義初始狀態
const initialState = { count: -1 };
//初始化函數
function init(initial) {// 確保初始計數值為正數return { count: Math.abs(initial.count) };
}
// 定義 reducer 函數
function counterReducer(state, action) {switch (action.type) {case 'increment':return { count: state.count + 1 };case 'decrement':return { count: state.count - 1 };case 'reset':return initialState;default:throw new Error();}
}
}// 在組件中使用
function Counter() {const [state, dispatch] = useReducer(counterReducer, initialState, init);//第三個參數可以傳入函數,這個函數允許你自定義初始化邏輯,而不是直接使用第二個參數 initialState作為初始狀態(對第二個參數進行預處理,如取abs)。當你需要對初始狀態進行一些計算或處理時return (<div><p>Count: {state.count}</p><button onClick={() => dispatch({ type: 'increment' })}>+1</button><button onClick={() => dispatch({ type: 'decrement' })}>-1</button><button onClick={() => dispatch({ type: 'reset' })}>Reset</button></div>);
}
·
useContext
和props的區別
- Props 是父組件向子組件傳遞數據的一種方式,從上往下傳遞,
- useContext 是一個 React Hook,允許你訂閱 React 的 Context 對象。Context 提供了一種在組件之間共享數據的方式
作用
Props 主要用于父子組件之間的通信,而 useContext 解決了跨層級組件間的數據共享問題。如果組件層次較深,為了將某個 prop 從根組件傳遞到深層嵌套的組件,可能需要在每一層中間組件中“透傳”這個 prop(即使這些中間組件并不使用該 prop),這被稱為“prop drilling“ 使用useContext可以避免prop drilling
過度依賴 Context 可能導致不必要的重新渲染,因為它本質上是全局的。而 Props 則更細粒度,僅影響接收它們的組件
使用樣例, 文件名為 ThemeContext.js,創造好了context,引用該文件后可以 useContext
import React, { createContext, useState, useContext } from 'react';// 創建 ThemeContext
export const ThemeContext = createContext();// 創建一個提供者組件來包裹需要訪問 context 的組件樹
export const ThemeProvider = ({ children }) => {const [theme, setTheme] = useState('light'); // 默認主題為 lightconst toggleTheme = () => {setTheme(prevTheme => prevTheme === 'light' ? 'dark' : 'light');};return (<ThemeContext.Provider value={{ theme, toggleTheme }}>{children}</ThemeContext.Provider>);
};
import React, { useContext } from 'react';
import { ThemeProvider, ThemeContext } from './ThemeContext'; // 假設文件名為 ThemeContext.js
import MiddleComponent from './MiddleComponent';function App() {const { theme, toggleTheme } = useContext(ThemeContext);return (<ThemeProvider><div className={`app ${theme}`}><button onClick={toggleTheme}>Toggle Theme</button><MiddleComponent /></div></ThemeProvider>);
}export default App;
import React from 'react';
import DeeplyNestedComponent from './DeeplyNestedComponent';function MiddleComponent() {return (<div><h2>Middle Component</h2><DeeplyNestedComponent /></div>);
}export default MiddleComponent;
import React, { useContext } from 'react';
import { ThemeContext } from './ThemeContext'; // 假設文件名為 ThemeContext.jsfunction DeeplyNestedComponent() {const { theme } = useContext(ThemeContext);return (<div className={`deeply-nested-component ${theme}`}><h3>Deeply Nested Component with {theme} theme</h3></div>);
}export default DeeplyNestedComponent;
useEffect
useEffect Hook 讓你可以執行副作用操作(如數據獲取、訂閱或手動 DOM 操作),并根據指定的依賴項數組來決定何時重新執行副作用
- 無依賴項: 在組件每次渲染后執行。
- 空數組([]): 僅在組件掛載和卸載時執行
- 依賴項數組: 當數組中的任何值發生變化時,effect將會重新運行。
import React, { useState, useEffect } from 'react';function Example() {const [count, setCount] = useState(0);useEffect(() => {console.log(`You clicked ${count} times`);return () => {// 清理函數console.log('清理工作');};}, [count]); // 只有 count 改變時觸發(注意 初始化的時候也會加載一次return (<div><p>You clicked {count} times</p><button onClick={() => setCount(count + 1)}>Click me</button></div>);
}
useMemo
useMemo Hook 用于記憶計算結果,避免重復計算。它接收一個創建函數和依賴項數組,只有當依賴項改變時才會重新計算返回值。
import React, { useState, useMemo } from 'react';function computeExpensiveValue(a, b) {console.log("Performing expensive computation...");return a + b;
}function Example({ a, b }) {const [count, setCount] = useState(0);const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);return (<><p>Memoized Value: {memoizedValue}</p><p>Count: {count}</p><button onClick={() => setCount(count + 1)}>Increase Count</button></>);
}
useCallBack
seCallback Hook 與 useMemo 類似,用于記憶函數定義。優化性能,特別是當將回調函數作為 props 傳遞給子組件時,可以防止子組件重新渲染。
import React, { useState, useCallback } from 'react';function ChildComponent({ onButtonClick }) {console.log("ChildComponent render");return <button onClick={onButtonClick}>Click Me!</button>;//即使父組件渲染,ChildComponent 接收到的 onButtonClick 回調不會改變, Click me Button不會重新渲染
}function ParentComponent() {const [count, setCount] = useState(0);const handleClick = useCallback(() => {console.log("Button clicked");}, []); // 空數組意味著這個回調永遠不會更新return (<><ChildComponent onButtonClick={handleClick} /><p>Count: {count}</p><button onClick={() => setCount(count + 1)}>Increase Count</button></>);
}