React中Hooks

概念:Hooks 是 React 16.8 版本引入的新特性,它可以让你在函数组件中使用 state 以及其他 React 特性。在此之前,只有 class 组件才能使用这些功能。Hooks 的引入,使得我们可以在不使用类的情况下构建 React 应用程序。

常见的Hooks

useState:用于声明状态变量
useEffect:用于处理组件的副作用
useContext:用于订阅 React 上下文
useReducer:用于管理组件状态
useCallback:用于缓存函数
useMemo:用于缓存计算结果
useRef:用于创建可变的 ref 对象
useImperativeHandle:用于自定义暴露给父组件的实例值
useLayoutEffect:与 useEffect 相同,但是会在所有DOM改变之后同步触发
useDebugValue:用于在 React 开发工具中显示自定义 hook 的标签
总的来说,Hooks 让我们在函数组件中也能使用 state 以及其他 React 特性,提高了组件逻辑复用性,同时使代码更加清晰易懂。

使用场景

1.useState

import React, { useState } from 'react';

function Example() {
  const [count, setCount] = useState(0); // 声明状态变量及其setter函数

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

注意事项:
useState只接受一个参数作为初始状态
状态更新会引起组件重新渲染,因此避免在主体渲染中调用setState
可以使用多个useState管理不同状态
2.useEffect

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

function Example() {
  const [data, setData] = useState([]);

  useEffect(() => {
    // 模拟网络请求
    const fetchData = setTimeout(() => {
      setData([1, 2, 3]);
    }, 2000);

    // 清理副作用
    return () => clearTimeout(fetchData);
  }, []); // 空数组确保只运行一次

  return <ul>{data.map(item => <li key={item}>{item}</li>)}</ul>;
}

注意事项:
第二个参数是一个数组,用于指定effect的依赖项,只有依赖项变化时才会重新执行
返回一个清理函数,用于清理副作用,如取消订阅等
空数组[]表示只在组件挂载和卸载时执行
3.useContext

import React, { createContext, useContext } from 'react';

const ThemeContext = createContext('light');

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar() {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return <button style={{ background: theme }}>I am styled by theme context!</button>;
}

注意事项:
需要先使用createContext创建Context对象
上层组件使用Provider提供数据
下层组件使用useContext获取数据
4.useReducer

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:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
    </>
  );
}

使用场景: 状态逻辑较复杂时,可以使用 Reducer 模式优化状态管理。
注意事项:
useReducer接收两个参数,第一个是reducer函数,第二个是初始状态
reducer函数根据不同的action决定如何更新状态
dispatch用于发送action从而更新状态
5.useCallback

import React, { useState, useCallback } from 'react';
function Parent() {
  const [count, setCount] = useState(0);
  const [name, setName] = useState('');

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

  return (
    <div>
      <input value={name} onChange={e => setName(e.target.value)} />
      <Child handleClick={handleClick} />
      <p>Count: {count}</p>
    </div>
  );
}

const Child = React.memo(({ handleClick }) => {
  console.log('Child rendered');
  return <button onClick={handleClick}>Click me</button>;
});

使用场景: 缓存函数实例,避免组件重新渲染时重复创建函数实例。
注意事项:
第二个参数是一个数组,用于指定依赖项,只有依赖项变化时才会重新创建函数实例
通常与React.memo或shouldComponentUpdate一起使用,提高性能
6.useMemo

import React, { useState, useMemo } from 'react';
function App() {
  const [count, setCount] = useState(0);
  const [name, setName] = useState('');

  const data = useMemo(() => {
    return { count, name };
  }, [count, name]);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <input value={name} onChange={e => setName(e.target.value)} />
      <Display data={data} />
    </div>
  );
}

function Display({ data }) {
  return <pre>{JSON.stringify(data, null, 2)}</pre>;
}

使用场景: 缓存计算结果,避免重复计算。
注意事项:
第二个参数是一个数组,用于指定依赖项,只有依赖项变化时才会重新计算
如果计算量非常小,使用可能引起额外开销,适合使用在计算量较大的场景

7.useImperativeHandle

import React, { useRef, forwardRef, useImperativeHandle } from 'react';
const Input = forwardRef((props, ref) => {
  const inputRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    },
  }));

  return <input ref={inputRef} {...props} />;
});

const App = () => {
  const inputRef = useRef();

  const focusInput = () => {
    inputRef.current.focus();
  };

  return (
    <div>
      <Input ref={inputRef} />
      <button onClick={focusInput}>Focus Input</button>
    </div>
  );
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值