一文快速上手React Hooks

257 阅读2分钟

Hooks 是一项新功能提案,可让您在不编写类的情况下使用 React 功能

为什么引入Hook(借鉴一下React官网)

  1. 在组件之间重用有状态逻辑很困难

React并没有为组件提供一种可重复使用行为的方法,使用 Hook ,您可以从组件中提取有状态逻辑,以便可以独立测试并重用。Hooks 允许您在不更改组件层次结构的情况下重用有状态逻辑。  这样可以轻松地在许多组件个之间或与社区共享 Hooks 。

  1. 复杂的组件变得难以理解

我们常常不得不维护一些组件,这些组件一开始很简单,但后来却变成了一堆难以管理的有状态逻辑和副作用。每个生命周期方法通常包含一组不相关的逻辑。例如,组件可能在componentDidMount 和 componentDidUpdate中执行一些数据获取。然而,相同的 componentDidMount 方法可能还包含一些不相关的逻辑,它们设置事件监听器,并在 componentWillUnmount 中执行清理。一起更改的相互关联的代码会被分离,但是完全不相关的代码最终会组合在一个方法中。这很容易引入错误和不一致。

  1. 人和机器都容易混淆的 类(class)

类(class) 可能是学习 React 的一大障碍。您必须了解 this 在 JavaScript 中是如何工作的, this 与多数语言中的工作方式有很大不同。您必须记住绑定事件处理程序。

useState

  • useState用于为函数组件引入状态(state);
  • useState 的唯一参数是初始状态(state);
  • useState 返回一对:current state(状态)值和一个允许你更新它的函数;
import React, { useState } from 'react';

const Index = () => {
  const [count, setCount] = useState(0);

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

export default Index;

特别说明:

useState 修改引用类型的state的时候,需要改变指针地址,才会触发渲染

useEffect

  • 可以将 useEffect Hook 视为 componentDidMountcomponentDidUpdate 和 componentWillUnmount 的组合

  • 每次渲染后 useEffect 都会运行

  • useEffect 具有副作用,像 addEventListener、setTimeout 等需要进行清理

  • 使用多个 Effects 来分离关注点

function FriendStatusWithCounter(props) {
  const [count, setCount] = useState(0);
  
  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

  const [isOnline, setIsOnline] = useState(null);
  
  useEffect(() => {
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });

  function handleStatusChange(status) {
    setIsOnline(status.isOnline);
  }
  // ...
}

useContext

  • 接受一个 context(上下文)对象(从 React.createContext 返回的值)并返回当前 context 值

  • 跨祖孙组件传递数据

const UserContext = createContext({
  name: 'zhangsan',
  age: 12,
  sex: 0,
});

const Child = () => {
  const userInfo = useContext(UserContext);

  return (
    <div>
      我是{userInfo.name},今年{userInfo.age},性别{userInfo.sex}
    </div>
  )
}

const Parent = () => {
  const [userInfo, setUserInfo] = useState({
    name: 'zhangsan',
    age: 12,
    sex: 0,
  });

  const changeName = () => {
    setUserInfo({
      ...userInfo,
      name: userInfo.name === 'lisi' ? 'zhangsan' : 'lisi',
    });
  }

  return (
    <div>
      <UserContext.Provider value={userInfo}>
        <Child />
      </UserContext.Provider>
      <button onClick={changeName}>修改name</button>
    </div>
  )
}

Hooks 使用规则

Hooks 是 JavaScript 函数,但在使用它们时需要遵循两个规则。

  • 只在顶层调用Hook,不要在循环,条件或嵌套函数中调用 Hook

  • 只在 React Functions 中调用 Hooks