对于新手 react 玩家来说,了解常用的 React Api 是一件重要的事情,这篇文章可以帮组你很快的了解常用 Api,帮助你在开发中快速而有效的完成任务。

React 中常用的五个 Hooks

useState

用于在函数组件中添加状态,状态的更新会触发组件重新渲染。

示例:

import React, { useState } from "react";

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

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

export default Counter;

useEffect

用于在函数组件中执行副作用操作,如数据获取、订阅、手动更改 DOM 等。它相当于 componentDidMountcomponentDidUpdatecomponentWillUnmount 的结合。

副作用一定要是改变的数据,像对象这种引用型的数据,虽然你主观认为数据改变了,但是并没有改变引用,所以特定监听不到。但是可以配合 useState 实现监听。

示例:

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

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

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

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

export default Example;

useContext

用于共享状态而无需手动通过每一级组件传递 props。

示例:

import React, { useContext } from "react";

const MyContext = React.createContext();

function MyComponent() {
  const value = useContext(MyContext);
  return <div>{value}</div>;
}

function App() {
  return (
    <MyContext.Provider value="Hello, World!">
      <MyComponent />
    </MyContext.Provider>
  );
}

export default App;

useReducer

用于更复杂的状态管理逻辑,类似于 useState,但适用于包含多个子值或复杂状态逻辑的情况。

示例:

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>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: "increment" })}>+</button>
      <button onClick={() => dispatch({ type: "decrement" })}>-</button>
    </div>
  );
}

export default Counter;

useRef

用于访问 DOM 元素或保存一个可变值,该值在组件重新渲染时不会改变。

示例:

import React, { useRef } from "react";

function TextInputWithFocusButton() {
  const inputEl = useRef(null);

  const onButtonClick = () => {
    inputEl.current.focus();
  };

  return (
    <div>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </div>
  );
}

export default TextInputWithFocusButton;

使用 useReducer 进行复杂状态管理

为什么使用 useReduceruseReducer 在处理包含多个子值或复杂状态逻辑时更合适。通过定义一个 reducer 函数,我们可以更清晰地管理状态更新逻辑。

示例:

jsx复制代码;
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>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: "increment" })}>+</button>
      <button onClick={() => dispatch({ type: "decrement" })}>-</button>
    </div>
  );
}

export default Counter;

使用 memo 进行组件优化

** 为什么使用 memo:**React.memo 是一个高阶组件,可以将组件包装在其中以避免不必要的重新渲染。React.memo 通过浅比较 props 来决定是否重新渲染组件。

示例:

import React, { memo } from "react";

const ChildComponent = memo(({ name }) => {
  console.log("ChildComponent rendered");
  return <div>Hello, {name}</div>;
});

function ParentComponent() {
  const [name, setName] = React.useState("John");

  return (
    <div>
      <ChildComponent name={name} />
      <button onClick={() => setName(name === "John" ? "Doe" : "John")}>
        Change Name
      </button>
    </div>
  );
}

export default ParentComponent;

在上述示例中,ChildComponent 只有在 name 改变时才会重新渲染。通过 React.memo 包装组件,可以有效地减少不必要的渲染,提高性能。

使用 useMemouseCallback 进行性能优化

useMemo

** 为什么使用 useMemo:**useMemo 用于缓存计算结果,从而避免在每次渲染时都进行耗时计算。

示例:

import React, { useMemo } from "react";

function Example({ items }) {
  const expensiveCalculation = (items) => {
    // 假设这里有一个耗时的计算
    return items.reduce((total, item) => total + item, 0);
  };

  const total = useMemo(() => expensiveCalculation(items), [items]);

  return <div>Total: {total}</div>;
}

export default Example;

useCallback

** 为什么使用 useCallback:**useCallback 用于缓存函数实例,从而避免在每次渲染时都创建新的函数实例,特别是在将函数传递给子组件时非常有用。

示例:

import React, { useState, useCallback } from "react";

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

  const increment = useCallback(() => {
    setCount((prevCount) => prevCount + 1);
  }, []);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

export default Example;

总结

这些示例展示了 React 中常用的 Hooks 及其使用场景。通过合理运用这些 Hooks,可以有效地管理组件状态、处理副作用、优化性能,提升开发效率和应用性能。