• 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>
    	);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    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>
    	);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    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>;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    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>
    	);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    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>
    	);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    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>
    	);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    四、不常用的 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} />;
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    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>;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3. useDebugValue:

    import React, { useDebugValue, useState } from 'react';
    
    function useCustomHook() {
    	const [count, setCount] = useState(0);
    	useDebugValue(`Count: ${count}`);
    	return count;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    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>
    	);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    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>
    	);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    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>;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    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>;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    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>;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  • 相关阅读:
    一文解读:阿里云 AI 基础设施的演进与挑战
    前端混合开发框架大对比:React Native vs. Flutter vs. Ionic
    物流监管:智慧仓储数据可视化监控平台
    金昌JCH文件批量转BMP/JPG图片脚本
    【C++】类和对象(下)
    系统集成|第十一章(笔记)
    由点汇聚成字的动效炫极了
    从0到1开始运营你的开源产品
    Linux - 任务管理
    使用深度2img预训练模型生成图像到图像--附源码
  • 原文地址:https://blog.csdn.net/ZSZ1805355272/article/details/132597264