深入理解React钩子:常用与高级用法全解析

React 钩子

一、常用的 React 钩子:

1. useState

用于在函数式组件中添加状态管理。它返回一个状态值和一个更新状态的函数,让你可以在组件中追踪和更新状态。

2. useEffect

用于在组件渲染完成后执行副作用操作,比如数据获取、订阅等。它接收一个回调函数和一个依赖数组,可以用来管理副作用的触发时机。

3. useContext

用于在组件中访问全局的上下文数据。它接收一个上下文对象,返回上下文中的数据。

4. useReducer

类似于 useState,但更适用于复杂的状态逻辑,它通过使用一个 reducer 函数来管理状态。

5. useCallback

用于缓存回调函数,以避免在每次渲染时创建新的回调函数。适用于性能优化。

6. useMemo

用于缓存计算结果,以避免在每次渲染时重复计算。适用于性能优化。

7. useState

用于在函数式组件中添加状态管理。它返回一个状态值和一个更新状态的函数,让你可以在组件中追踪和更新状态。

8. useContext

用于在组件中访问全局的上下文数据。它接收一个上下文对象,返回上下文中的数据。

9. useReducer

类似于 useState,但更适用于复杂的状态逻辑,它通过使用一个 reducer 函数来管理状态。

10. useCallback

用于缓存回调函数,以避免在每次渲染时创建新的回调函数。适用于性能优化。

11. useMemo

用于缓存计算结果,以避免在每次渲染时重复计算。适用于性能优化。

二、不常用的 React 钩子:

  1. useImperativeHandle:用于自定义暴露给父组件的实例值,通常与 forwardRef 一起使用。
  2. useLayoutEffect:与 useEffect 类似,但在 DOM 更新之后同步执行,适用于需要操作 DOM 布局的情况。
  3. useDebugValue:用于在 React 开发者工具中提供自定义钩子的标签和调试信息。
  4. useRef:用于在组件渲染之间保持变量的稳定引用,不触发重新渲染。还可以用于获取 DOM 元素的引用。
  5. useTransition:用于管理异步更新的状态,可以平滑地在不同状态之间切换。
  6. useMutableSource:用于自定义数据源,以供 useTransition 和 Concurrent Mode 使用。
  7. useDeferredValue:与 useTransition 一起使用,用于推迟渲染较不重要的数据。
  8. useSyncExternalStore:与外部数据源集成的实验性 API,用于从外部数据源同步状态。

三、常用的 React 钩子示例:

1. useState:

import React, { useState } from 'react';
function Counter() {
	const [count, setCount] = useState(0);
	return (
		<div>
			<p>Count: {count}</p>
			<button onClick={() => setCount(count + 1)}>Increment</button>
		</div>
	);
}

2. useEffect:

import React, { useState, useEffect } from 'react';
function DataFetching() {
	const [data, setData] = useState([]);
	useEffect(() => {
		fetch('https://api.example.com/data')
		.then(response => response.json())
		.then(data => setData(data));
	}, []);
	return (
		<div>
			{data.map(item => <p key={item.id}>{item.name}</p>)}
		</div>
	);
}

3. useContext:

import React, { useContext } from 'react';
const ThemeContext = React.createContext('light');
function ThemedText() {
	const theme = useContext(ThemeContext);
	return <p className={theme}>This is themed text.</p>;
}

4. useReducer:

import React, { useReducer } from 'react';
const initialState = { count: 0 };
function countReducer(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(countReducer, initialState);
return (
	<div>
		<p>Count: {state.count}</p>
		<button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
		<button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
	</div>
	);
}

5. useCallback:

import React, { useState, useCallback } from 'react';
function Button({ onClick }) {
	console.log('Button rendered');
	return <button onClick={onClick}>Click me</button>;
}

function Parent() {
	const [count, setCount] = useState(0);
	const handleClick = useCallback(() => {
		setCount(count + 1);
	}, [count]);

	return (
		<div>
			<p>Count: {count}</p>
			<Button onClick={handleClick} />
		</div>
	);
}

6. useMemo:

import React, { useState, useMemo } from 'react';
       
function ExpensiveCalculation() {
	console.log('Expensive calculation');
	// Simulating a time-consuming calculation
	return 5 + 10;
}

function Parent() {
	const [count, setCount] = useState(0);

	const result = useMemo(() => {
		return ExpensiveCalculation();
	}, [count]);
       
	return (
		<div>
			<p>Result: {result}</p>
			<button onClick={() => setCount(count + 1)}>Increment</button>
		</div>
	);
}

四、不常用的 React 钩子示例:

1. useImperativeHandle:

import React, { useRef, forwardRef, useImperativeHandle } from 'react';

const FancyInput = forwardRef((props, ref) => {
	const inputRef = useRef();

	useImperativeHandle(ref, () => ({
		focus: () => {
			inputRef.current.focus();
		}
	}));
	return <input ref={inputRef} />;
});

2. useLayoutEffect:

import React, { useState, useLayoutEffect } from 'react';
       
function LayoutEffectExample() {
	const [width, setWidth] = useState(0);

	useLayoutEffect(() => {
		setWidth(document.documentElement.clientWidth);
	}, []);
       
	return <p>Window width: {width}</p>;
}

3. useDebugValue:

import React, { useDebugValue, useState } from 'react';

function useCustomHook() {
	const [count, setCount] = useState(0);
	useDebugValue(`Count: ${count}`);
	return count;
}

4. useRef:

import React, { useRef } from 'react';

function FocusableInput() {
	const inputRef = useRef();

	const focusInput = () => {
		inputRef.current.focus();
	};
	return (
		<div>
			<input ref={inputRef} />
			<button onClick={focusInput}>Focus Input</button>
		</div>
	);
}

5. useTransition:

import React, { useState, useTransition } from 'react';
       
function AsyncContent() {
	const [data, setData] = useState([]);
	const [startTransition, isPending] = useTransition();
       
	const fetchData = () => {
		startTransition(() => {
			fetch('https://api.example.com/data')
				.then(response => response.json())
				.then(data => setData(data));
		});
	};
	return (
           <div>
             <button onClick={fetchData} disabled={isPending}>Fetch Data</button>
             {data.map(item => <p key={item.id}>{item.name}</p>)}
           </div>
	);
}

6.useMutableSource

useMutableSource 是一个用于实验性的 API,通常用于与 React 的 Concurrent Mode 结合使用。它允许你创建一个可变数据源,可以在更新时传递给 React,以实现异步更新的状态。

import React, { useMutableSource } from 'react';

const dataSource = {
	// 在这里定义你的数据源方法
};
    
    function CustomComponent() {
      const mutableSource = useMutableSource(dataSource);
    
      return <div>{mutableSource.getData()}</div>;
    }

7.useDeferredValue

useDeferredValue 与 useTransition 一起使用,用于将某些数据的渲染推迟到未来帧,以平滑地处理异步数据的更新。

import React, { useState, useTransition, useDeferredValue } from 'react';

function AsyncContent() {
	const [data, setData] = useState([]);
	const [startTransition, isPending] = useTransition();
	const fetchData = () => {
		startTransition(() => {
          fetch('https://api.example.com/data')
            .then(response => response.json())
            .then(data => setData(data));
        });
	};
    
	return (
		<div>
			<button onClick={fetchData} disabled={isPending}>
				Fetch Data
			</button>
			{data.map(item => (
				<p key={item.id}>
					<DeferredText text={item.name} />
				</p>
			))}
		</div>
	);
}
    
function DeferredText({ text }) {
	const deferredText = useDeferredValue(text);
	return <span>{deferredText}</span>;
}

8.useSyncExternalStore

useSyncExternalStore 是一个实验性 API,用于将 React 组件状态与外部数据源同步,适用于从外部数据源获取数据并同步状态。

import React, { useSyncExternalStore } from 'react';
    
const externalStore = {
	// 定义与外部数据源交互的方法
};
    
function SyncedComponent() {
	const syncedData = useSyncExternalStore(externalStore);
	return <div>Data from external store: {syncedData}</div>;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

俎树振

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值