React Hook

84 阅读3分钟

React Hook

React Hook是一种函数,它可以让我们在React函数组件中使用状态和其他React特性。使用React Hook,我们不需要编写类组件或使用高阶组件或渲染属性来实现组件之间的状态共享。相反,我们可以直接在函数组件中使用Hook来处理状态和副作用。React Hook包括useState、useEffect、useContext、useReducer、useCallback、useMemo、useRef、useImperativeHandle和useLayoutEffect。

使用useState

useState是最常用的React Hook之一,它允许我们在函数组件中添加状态。我们可以使用useState创建一个状态变量和一个更新该变量的函数。

--javascripttypescriptbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

import React, { useState } from 'react';

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

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

在上面的例子中,我们创建了一个名为count的状态变量和一个名为setCount的函数。我们可以在函数组件中使用count变量来显示计数器的值,并使用setCount函数来更新计数器的值。

使用useEffect

useEffect是另一个常用的React Hook,它允许我们在组件渲染后执行副作用。我们可以使用useEffect创建一个函数,该函数在组件渲染后执行。

--javascripttypescriptbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

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

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

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

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

在上面的例子中,我们创建了一个useEffect函数,该函数设置文档标题为计数器的值。每次计数器的值更新时,useEffect函数都会重新运行。这是因为我们没有指定useEffect的依赖项。如果我们想要控制useEffect的执行,我们可以传递一个数组作为第二个参数,该数组包含useEffect的依赖项。如果依赖项没有更改,useEffect将不会重新运行。

--javascripttypescriptbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

useEffect(() => {
  document.title = `You clicked ${count} times`;
}, [count]);

在上面的例子中,我们传递了[count]作为useEffect的依赖项。这意味着只有当计数器的值更改时,useEffect才会重新运行。

使用useContext

useContext是另一个常用的React Hook,它允许我们在组件之间共享状态。我们可以使用useContext创建一个上下文对象,并将其传递给需要访问该上下文的组件。

--javascripttypescriptbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

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

const CountContext = React.createContext();

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

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

function DisplayCount() {
  const count = useContext(CountContext);

  return (
    <div>
      <p>The current count is {count}</p>
    </div>
  );
}

在上面的例子中,我们创建了一个名为CountContext的上下文对象,并在Counter组件中将计数器的值传递给它。然后,我们使用useContext在DisplayCount组件中访问CountContext。这使得DisplayCount组件可以访问计数器的值,而不需要使用prop或状态提升。

使用useReducer

useReducer是另一个React Hook,它允许我们使用Redux-style的reducer函数来处理组件状态。我们可以使用useReducer创建一个状态对象和一个reducer函数。

--javascripttypescriptbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

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 (
    <div>
      <p>You clicked {state.count} times</p>
      <button onClick={() => dispatch({ type: 'increment' })}>
        Click me
      </button>
      <button onClick={() => dispatch({ type: 'decrement' })}>
        Click me
      </button>
    </div>
  );
}

在上面的例子中,我们创建了一个名为initialState的初始状态对象和一个名为reducer的reducer函数。然后,我们使用useReducer创建了一个状态对象和一个名为dispatch的函数。dispatch函数允许我们在组件中触发reducer函数,并更新状态对象。

创建自定义Hooks

除了使用React提供的Hooks,我们还可以创建自定义Hooks来封装常见的行为。自定义Hook是一个普通函数,它可以使用任何React Hook。我们可以使用自定义Hook来封装某些状态或副作用,并将其重用在多个组件中。

--javascripttypescriptbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

import { useState, useEffect } from 'react';

function useWindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);

  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);
    window.addEventListener('resize', handleResize);
		return () => {
			window.removeEventListener('resize', handleResize);
		};		
	}, []);

return width;
}

在上面的例子中,我们创建了一个名为useWindowWidth的自定义Hook。它使用useState来保存窗口宽度,并使用useEffect来订阅窗口大小的变化。当组件使用useWindowWidth时,它将返回当前窗口宽度,并在窗口大小变化时自动更新。

总结

React Hook提供了一种更简单、更直接的方式来处理组件状态和副作用。使用React Hook,我们可以避免编写类组件或使用高阶组件或渲染属性来实现组件之间的状态共享。在本文中,我们讨论了如何使用useState、useEffect、useContext、useReducer和自定义Hook来管理状态和副作用。希望这篇文章对你有所帮助。