react hook

功能优点

  • Hook使你在无需修改组件结构的情况下复用状态逻辑。
  • class缺点:不能很好的压缩,并且会使热重载出现不稳定的情况,比较"重"。hook更简洁,代码量少,官方推荐。

useEffect

  • 作用:指定一个函数,组件每渲染(加载和更新)一次,该函数就自动执行一次(React的class组件没有提供这样的方法。)
  • 与class 组件中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 具有相同的用途,只不过被合并成了一个 API
  • 解决了class中生命周期函数经常包含不相关的逻辑,但又把相关逻辑分离到了几个不同方法中的问题
    class的写法:
componentDidMount() {
    document.title = `You clicked ${this.state.count} times`;
  }
  componentDidUpdate() {
    document.title = `You clicked ${this.state.count} times`;
  }

hook的写法

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(() => {
  document.title = `You clicked ${count} times`;
}, [count]); // 仅在 count 更改时更新
  • 如果第二个参数是一个空数组,就表明没有任何依赖项。因此,函数这时只会在组件加载进入 DOM 后执行一次,后面组件重新渲染,就不会再次执行

  • 常见用途有下面几种:

    • 获取数据(data fetching)
    • 事件监听或订阅(setting up a subscription)
    • 改变 DOM(changing the DOM)
    • 输出日志(logging)
  • useEffect()允许返回一个函数,在组件卸载时,执行该函数,清理hook

 useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });
  • 执行时机:浏览器完成布局与绘制之后,在一个延迟事件中被调用

useState

  • 通过在函数组件里调用它来给组件添加一些内部state。React 会在重复渲染时保留这个 state。
  • useState 会返回一对值:当前状态和一个让你更新它的函数,你可以在事件处理函数中或其他一些地方调用这个函数。它类似 class 组件的 this.setState,但是它不会把新的 state 和旧的 state 进行合并。useState 唯一的参数就是初始 state
import React, { useState } from 'react';

function Example() {
  // 声明一个叫 "count" 的 state 变量
  const [count, setCount] = useState(0);
//可以直接用 count:
<p>You clicked {count} times</p>
//更新 State
<button onClick={() => setCount(count + 1)}>
        Click me
      </button>
  • 如果新的 state 需要通过使用先前的 state 计算得出,那么可以将函数传递给 setState
const [count, setCount] = useState(initialCount);
<button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
  • 如果你的更新函数返回值与当前 state 完全相同(Object.is 比较算法),则随后的重渲染会被完全跳过。
  • 与 class 组件中的 setState 方法不同,useState 不会自动合并更新对象。你可以用函数式的 setState 结合展开运算符来达到合并更新对象的效果。
const [state, setState] = useState({});
setState(prevState => {
  // 也可以使用 Object.assign
  return {...prevState, ...updatedValues};
});

自定义hook

  • 自定义 Hook,可以将组件逻辑提取到可重用的函数中。每次使用自定义 Hook 时,其中的所有state和副作用都是完全隔离的。
  • 自定义 Hook 是一个函数,其名称以 “use” 开头(否则React将无法自动检查你的Hook是否违反了Hook的规则),函数内部可以调用其他的Hook

额外的 Hook

useReducer
  • useState 的替代方案
  • 适用情况:state 逻辑较复杂且包含多个子值,或者下一个 state 依赖于之前的 state 等
useMemo
  • 传入 useMemo 的函数会在渲染期间执行,请不要在这个函数内部执行不应该在渲染期间内执行的操作,诸如副作用这类的操作属于 useEffect 的适用范畴,而不是 useMemo
  • 可以把 useMemo 作为性能优化的手段
useCallback
  • 相当于 useMemo
useRef

一个常见的用例便是命令式地访问子组件:

function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
  // `current` 指向已挂载到 DOM 上的文本输入元素
  inputEl.current.focus();
};
return (
  <>
    <input ref={inputEl} type="text" />
    <button onClick={onButtonClick}>Focus the input</button>
  </>
);
}

Hook 规则

  • 只在最顶层使用 Hook,以及任何 return 之前调用,不要在循环,条件或嵌套函数中调用 Hook,这样可以确保Hook在每一次渲染中都按照同样的顺序被调用。
  • 只在React函数或自定义Hook中调用 Hook,不要在普通的JavaScript函数中调用Hook
  • 如果我们想要有条件地执行一个effect
  • 能在React的函数组件中调用 Hook。不要在其他 JavaScript 函数中调用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值