作用
- useState:用于在函数组件中引入状态,返回一个状态变量和一个更新状态的函数
- useEffect:用于在函数组件中执行副作用,接受一个函数作为参数,该函数会在组件渲染后执行,可以返回一个清理函数
- useContext:用于在函数组件中访问 Context 对象,接受一个 Context 对象作为参数,返回该 Context 的当前值
- useMemo:用于在函数组件中缓存计算结果,避免重复计算,接受一个创建函数和一个依赖数组作为参数,返回该创建函数的最新返回值
- useCallback:用于在函数组件中缓存函数,避免不必要的重新渲染,接受一个内联回调和一个依赖数组作为参数,返回该回调的 memoized 版本
- useRef:用于在函数组件中创建和访问 ref 对象,接受一个初始值作为参数,返回一个可变的 ref 对象,其 current 属性指向初始值或最新的值
- useLayoutEffect:用于在函数组件中读取 DOM 布局并同步触发重渲染,与 useEffect 类似,但会在 DOM 更新后同步执行
- useReducer:用于在函数组件中管理复杂的状态逻辑,接受一个 reducer 函数和一个初始状态作为参数,返回一个状态变量和一个 dispatch 函数
- useImperativeHandle:用于在函数组件中自定义暴露给父组件的 ref 值,接受一个 ref 对象和一个创建函数作为参数,返回该创建函数的返回值,并赋给 ref 对象的 current 属性
- useDebugValue:用于在函数组件中显示自定义的 Hook 标签,接受一个标签值或者一个生成标签值的函数作为参数,在 React 开发者工具中显示
- useId:用于在函数组件中生成一个唯一的标识符,可以用于关联 label 和 input 等元素,或者生成 DOM 元素的 id 属性
- useSyncExternalStore:用于在函数组件中订阅和读取外部数据源,例如 Redux、MobX 等,它可以与 React 的并发渲染特性兼容,例如选择性 hydration 和 time slicing
- useDeferredValue:用于在函数组件中延迟更新某个值,直到浏览器有空闲时间,它可以避免因为频繁的状态更新而导致的性能问题
用法:
- useState:用于在函数组件中引入状态,返回一个状态变量和一个更新状态的函数
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
const decrement = () => setCount(count - 1);
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
</div>
);
}
- useEffect:用于在函数组件中执行副作用,接受一个函数作为参数,该函数会在组件渲染后执行,可以返回一个清理函数
import React, { useState, useEffect } from 'react';
function DataFetching() {
const [data, setData] = useState(null);
useEffect(() => {
// 在组件挂载后获取数据
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => setData(data));
// 在组件卸载前进行清理工作
return () => {
// 取消订阅或清除计时器等
};
}, []);
return (
<div>
{data ? (
<ul>
{data.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
) : (
<p>Loading data...</p>
)}
</div>
);
}
- useContext:用于在函数组件中访问 Context 对象,接受一个 Context 对象作为参数,返回该 Context 的当前值
import React, { useContext } from 'react';
const ThemeContext = React.createContext('light');
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button style={{ background: theme }}>Click Me</button>;
}
function App() {
return (
<ThemeContext.Provider value="dark">
<ThemedButton />
</ThemeContext.Provider>
);
}
- useMemo:用于在函数组件中缓存计算结果,避免重复计算,接受一个创建函数和一个依赖数组作为参数,返回该创建函数的最新返回值
import React, { useState, useMemo } from 'react';
function ExpensiveCalculation({ number }) {
// 使用useMemo缓存计算结果,只有当number发生变化时才重新计算
const result = useMemo(() => {
console.log('Calculating...');
return number * 2;
}, [number]);
return <p>Result: {result}</p>;
}
- useCallback:用于在函数组件中缓存函数,避免不必要的重新渲染,接受一个内联回调和一个依赖数组作为参数,返回该回调的 memoized 版本
import React, { useState, useCallback } from 'react';
function Counter() {
const [count, setCount] = useState(0);
// 使用useCallback缓存回调函数,以避免每次渲染都创建新的函数
const increment = useCallback(() => setCount(count + 1), [count]);
const decrement = useCallback(() => setCount(count - 1), [count]);
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
</div>
);
}
- useRef:用于在函数组件中创建和访问 ref 对象,接受一个初始值作为参数,返回一个可变的 ref 对象,其 current 属性指向初始值或最新的值
import React, { useRef } from 'react';
function FocusInput() {
const inputRef = useRef(null);
const handleClick = () => {
// 使用inputRef.current来获取DOM元素的引用
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} />
<button onClick={handleClick}>Focus Input</button>
</div>
);
}
- useLayoutEffect:用于在函数组件中读取 DOM 布局并同步触发重渲染,与 useEffect 类似,但会在 DOM 更新后同步执行
import React, { useState, useLayoutEffect, useRef } from 'react';
function MeasureElement() {
const [width, setWidth] = useState(0);
const ref = useRef(null);
useLayoutEffect(() => {
// 获取DOM元素的宽度
setWidth(ref.current.getBoundingClientRect().width);
}, []);
return (
<div>
<div ref={ref}>Measure this element</div>
<p>Width: {width}px</p>
</div>
);
}
- useReducer:用于在函数组件中管理复杂的状态逻辑,接受一个 reducer 函数和一个初始状态作为参数,返回一个状态变量和一个 dispatch 函数
import React, { useReducer } from 'react';
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
case 'DECREMENT':
return { count: state.count - 1 };
default:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
const increment = () => dispatch({ type: 'INCREMENT' });
const decrement = () => dispatch({ type: 'DECREMENT' });
return (
<div>
<p>Count: {state.count}</p>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
</div>
);
}
- useImperativeHandle:用于在函数组件中自定义暴露给父组件的 ref 值,接受一个 ref 对象和一个创建函数作为参数,返回该创建函数的返回值,并赋给 ref 对象的 current 属性
import React, { useRef, useImperativeHandle, forwardRef } from 'react';
// 子组件
const ChildComponent = forwardRef((props, ref) => {
const inputRef = useRef(null);
// 使用useImperativeHandle来定义向父组件暴露的实例值
useImperativeHandle(ref, () => ({
focusInput: () => {
inputRef.current.focus();
},
}));
return <input ref={inputRef} />;
});
// 父组件
function ParentComponent() {
const childRef = useRef(null);
const handleClick = () => {
// 调用子组件暴露的方法
childRef.current.focusInput();
};
return (
<div>
<ChildComponent ref={childRef} />
<button onClick={handleClick}>Focus Input</button>
</div>
);
}
- useDebugValue:用于在函数组件中显示自定义的 Hook 标签,接受一个标签值或者一个生成标签值的函数作为参数,在 React 开发者工具中显示
import React, { useState, useDebugValue } from 'react';
function useCustomHook(initialValue) {
const [value, setValue] = useState(initialValue);
// 在React开发者工具中显示自定义hook标签
useDebugValue(`Custom hook value: ${value}`);
return [value, setValue];
}
function ExampleComponent() {
const [count, setCount] = useCustomHook(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
- useId:用于在函数组件中生成一个唯一的标识符,可以用于关联 label 和 input 等元素,或者生成 DOM 元素的 id 属性
import { useId } from 'react';
function MyComponent() {
// 生成一个唯一的标识符,例如 "input-0"
const inputId = useId();
return (
<div>
<label htmlFor={inputId}>Name</label>
<input id={inputId} type="text" />
</div>
);
}
- useSyncExternalStore:用于在函数组件中订阅和读取外部数据源,例如 Redux、MobX 等,它可以与 React 的并发渲染特性兼容,例如选择性 hydration 和 time slicing。它接受三个参数:subscribe、getSnapshot 和 getServerSnapshot,并返回数据源的当前值
import { useSyncExternalStore } from 'react';
function MyComponent() {
// 订阅和读取 Redux store
const state = useSyncExternalStore(
// subscribe 函数,注册一个回调,在 store 变化时调用
(callback) => store.subscribe(callback),
// getSnapshot 函数,返回 store 的当前值
() => store.getState(),
// getServerSnapshot 函数(可选),返回服务端渲染时的 store 值
() => store.getState()
);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => store.dispatch({ type: 'increment' })}>
Increment
</button>
</div>
);
}
- useDeferredValue:用于在函数组件中延迟更新某个值,直到浏览器有空闲时间,它可以避免因为频繁的状态更新而导致的性能问题
import { useState, useDeferredValue } from 'react';
function MyComponent() {
// 定义一个状态变量 text
const [text, setText] = useState('');
// 定义一个状态变量 count
const [count, setCount] = useState(0);
// 定义一个延迟更新的状态变量 deferredText
const deferredText = useDeferredValue(text);
// 定义一个延迟更新的状态变量 deferredCount
const deferredCount = useDeferredValue(count, { timeoutMs: 1000 });
return (
<div>
<input value={text} onChange={(e) => setText(e.target.value)} />
<p>Text: {text}</p>
<p>Deferred Text: {deferredText}</p>
<p>Current Count: {count}</p>
<p>Deferred Count: {deferredCount}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}