React16.8中Hooks详解

一、React Hooks(钩子)是什么

Introducing Hooks

React哲学:一切皆组件

类组件

class Counter extends Component {
    render () {
        return "Hello World"
    }
}
复制代码

函数组件

const Counter = () => {
    return "Hello World"
}
复制代码

为什么说函数式组件更优?

  1. 简单易懂
  2. 更符合React哲学,可以理解为React就是一个画UI的工具,符合UI=f(state)的原则
  3. 函数式编程

有hooks之前,为什么React需要类组件?

  1. 需要状态(state)
class Counter extends Component {
    state = {
        count: 0
    }
}
复制代码
  1. 需要生命周期函数
shouldComponentUpdate () { // 减少render渲染
    return true
}
复制代码
  1. 需要副作用操作(非纯函数)

副作用:调用ajax等

纯函数:每次输入的参数一样,那么每次返回的结果都相同。不要改全局变量,不要做ajax请求,不要去做异步操作等

componentDidMount () {
    fetchAPI().then(res => {
        this.setState({count: res})
    })
}
复制代码

能否让函数组件拥有这些功能?

const Counter = () => {
    return `
    想拥有,可是我没办法拥有状态,也没有生命周期函数,更不要说副作用操作了
    `
}
复制代码

Hooks拥有了这些功能

useState 状态管理
useEffect 生命周期函数
useContext 
等等...
复制代码

二、React Hooks带来哪些好处

useState: 在函数中管理状态

const Counter = () => {
    const [count, setCount] = useState(0) // 解构  初始值0
    const increment = () => setCount( count + 1 )
    return (
      <>
        <h1>{count}</h1>
        <button onClick={increment}>+</button>
      </>
    )
}
复制代码

useState的返回值是什么?

const [count, setCount] = useState(0)
可以改为下面的写法:
const state = useState(0)
const count = state[0]
const setCount = state[1]
复制代码

三、常用 Hooks 使用技巧

HoC : Higher order Component(With开头)

有了useState这个hook之后,就可以在组件里管理状态了

useState 一般写在函数的最上面
useState:返回结果可以任意取名
const [count, setCount] = useState(0)
也可写成
const  [count, updateCount] = useState(0)

useState是怎么做到的?
想象一下React为每一次useState调用分配一个“空间”
React通过useState调用顺序辨别各个“空间”,很简单,就是通过调用顺序来区分的!
复制代码

useState执行顺序必须一致!

不能写在if判断里,如下

const Counter = () => {
    const [count, setCount] = useState(0)
    if (count % 2 === 0) {
        const [bar, setBar] = useState(null) // 不能这么写
    }
    const [foo, setFoo] = useState("foo")
}


const [count, setCount] = useState(0) // 两个useState 根据调用顺序区分
const [name, setName] = useState("Fruit Bro") // 两个useState 根据调用顺序区分

setCount(count + 1)
setCount也是异步的,是setState的变种!
复制代码

useEffect:有机会做副作用操作

componentDidMount 用于在mount过程结束时的副作用
componentDidUpdate 用于在update过程结束时的副作用

useEffect = componentDidMount + componentDidUpdate
复制代码

useEffect模拟componentDidMount

useEffect(() => {
    // 每次mount或update都会调用到这里
})

useEffect(() => {
    // 只有mount时调用这里
},[]) // []代表依赖的数据
复制代码

useEffect模拟componentDidUnmount

useEffect(() => {
    // 只有mount时调用这里
    return () => {
        // 只有unmount时调用这里
    }
},[])
复制代码

hooks特有而类组件没有的是componentDidUnupdate,类似componentDidUnmount

useEffect模拟componentDidUpdate

const mounted = useRef() // useRef()不管调用多少次,返回的结果完全是一样的
useEffect(() => {
  if (!mounted.current) { 
  // 初次mounted,其实有用的就是current
      mounted.current = true
  } else {
      // do componentDidUpdate logic
  }
})
复制代码

ref可以访问真正的dom,但在React中,是非常介意直接操作真实DOM的,因此用vitural dom

注意:每一次渲染都有独立的props和state,每一次渲染使用hooks,函数组件的每一次渲染,无论是mount还是update,不管是第几次update,它都有独立的props和state

const Counter = () => {
    const [count, setCount] = useState(0)
    const onClick = () => {
        setCount(count + 1)
        setTimeout(() => {
        // 返回0的原因,初次为0,只有再次渲染的时候count才会为1,而每次渲染都有独立的props和state,因此新的渲染不会影响上一次的值
            alert(count) // 0 每一次新的执行就是一次新的开始
        }, 1000)
    }
    return (
      <>
        <h1>{count}</h1>
        <button onClick={onClick}>+</button>
      </>
    )
}
复制代码

useContext: 简化Context的使用

Hooks之前
<Context.Consumer>
  {contextValue => <h1>{contextValue}</h1>}
</Context.Consumer>

Hooks之后
const contextValue = useContext(Context)

<h1>{contextValue}</h1>
复制代码

四、React Hooks有哪些好处

Hooks的好处

  1. 降低了组件的复杂性

    1.1 完全使用函数组件

    1.2 无需生命周期函数

    1.3 更好的状态管理

  2. 更好的代码重用性

    2.1 传统的代码重用方式 组件、高阶组件(HoC)、render props模式

    2.2 Hooks下的代码重用方式:函数

定制Hooks: 函数形式的代码重用
// Beacon 计数
const useBeacon = () => {
    const [renderCount, setRenderCount] = useState(0)
    
    useEffect(() => {
        sendBeacon()
    })
}
// 重用
const Foo = () => {
    useBeacon();
    ...
}

const Bar = () => {
    useBeacon();
    ...
}
复制代码

五、如何迁移到Hooks

React v16.8.0开始正式支持Hooks

原有类组件功能依然支持

业界趋势将是向函数组件倾斜

迁移策略

了解Hooks

对新组建使用Hooks

逐步替换原有类组件

hooks如何处理类组件的shouldComponentUpdate来做性能优化 memo

如有错误,欢迎指正!谢谢!

转载于:https://juejin.im/post/5cbb4f77e51d456e7d189f85

React Hooks 是 React 16.8 新增的特性,它可以让你在函数组件使用 state、生命周期钩子等 React 特性。使用 Hooks 可以让你写出更简洁、可复用且易于测试的代码。 React Hooks 提供了一系列的 Hook 函数,包括 useState、useEffect、useContext、useReducer、useCallback、useMemo、useRef、useImperativeHandle、useLayoutEffect 和 useDebugValue。每个 Hook 都有特定的用途,可以帮助你处理不同的问题。 下面是 React Hooks 的一些常用 Hook 函数: 1. useState useState 是最常用的 Hook 之一,它可以让你在函数组件使用 state。useState 接受一个初始状态值,并返回一个数组,数组的第一个值是当前 state 值,第二个值是更新 state 值的函数。 ``` const [count, setCount] = useState(0); ``` 2. useEffect useEffect 可以让你在组件渲染后执行一些副作用操作,比如订阅事件、异步请求数据等。useEffect 接受两个参数,第一个参数是一个回调函数,第二个参数是一个数组,用于控制 useEffect 的执行时机。 ``` useEffect(() => { // 这里可以执行副作用操作 }, [dependencies]); ``` 3. useContext useContext 可以让你在组件树获取 context 的值。它接受一个 context 对象,并返回该 context 的当前值。 ``` const value = useContext(MyContext); ``` 4. useRef useRef 可以让你在组件之间共享一个可变的引用。它返回一个对象,该对象的 current 属性可以存储任何值,并在组件的生命周期保持不变。 ``` const ref = useRef(initialValue); ref.current = value; ``` 5. useCallback useCallback 可以让你缓存一个函数,以避免在每次渲染时都创建一个新的函数实例。它接受一个回调函数和一个依赖数组,并返回一个 memoized 的回调函数。 ``` const memoizedCallback = useCallback(() => { // 这里是回调函数的逻辑 }, [dependencies]); ``` 6. useMemo useMemo 可以让你缓存一个计算结果,以避免在每次渲染时都重新计算。它接受一个计算函数和一个依赖数组,并返回一个 memoized 的计算结果。 ``` const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]); ``` 以上就是 React Hooks 的一些常用 Hook 函数,它们可以帮助你更好地处理组件状态、副作用、上下文和性能优化等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值