ReactHook基本概念
Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性
从官网的这句话中,我们可以明确的知道,Hook增加了函数式组件中state的使用,在之前函数式组件是无法拥有自己的状态,只能通过props以及context来渲染自己的UI,而在业务逻辑中,有些场景必须要使用到state,那么我们就只能将函数式组件定义为class组件。而现在通过Hook,我们可以轻松的在函数式组件中维护我们的状态,不需要更改为class组件。
React Hooks要解决的问题是状态共享,这里的状态共享是指共享状态逻辑复用,并不是指数据之间的共享。我们知道在React Hooks之前,解决状态逻辑复用问题,我们通常使用higher-order components和render-props,那么既然已经有了这两种解决方案,为什么React开发者还要引入React Hook?对于higher-order components和render-props,React Hook的优势在哪?
React Hook动机
React Hook是官网提出的又一种全新的解决方案,我们先看一下React Hook提出的动机
- 在组件之间复用状态逻辑很难
- 复杂组件变得难以理解
- 难以理解的 class
下面说说我对这三个动机的理解:
在组件之间复用状态逻辑很难
在之前,我们通过高阶组件(Higher-Order Components)和渲染属性(Render Props)来解决状态逻辑复用困难的问题。很多库都使用这些模式来复用状态逻辑,比如我们常用redux、React Router。高阶组件、渲染属性都是通过组合来一层层的嵌套共用组件,这会大大增加我们代码的层级关系,导致层级的嵌套过于夸张。从React的devtool我们可以清楚的看到,使用这两种模式导致的层级嵌套程度
render Props

高阶组件

对于高阶组件来说,如果你没有对组件手动设置 name/displayName,就会遇到更严重的问题,那就是一个个匿名组件嵌套。毕竟上面 render props 的嵌套至少能知道组件名。
复杂组件变得难以理解
在不断变化的业务需求中,组件逐渐会被状态逻辑以及副作用充斥,每个生命周期常常会包含一些不相关的逻辑。我们写代码通常都依据函数的单一原则,一个函数一般只处理一件事,但在生命周期钩子函数中通常会同时做很多事情。比如,在我们需要在componentDidMount中发起ajax请求获取数据,同时有时候也会把事件绑定写在此生命周期中,甚至有时候需要在componentWillReceiveProps中对数据进行跟componentDidMount一样的处理。
难以理解的class
个人觉得使用class组件这种还是可以的,只要了解了class的this指向绑定问题,其实上手的难度不大。大家要理解,这并不是 React 特有的行为;这其实与 JavaScript 函数工作原理有关。所以只要了解好JS函数工作原理,其实this绑定都不是事。只是有时候为了保证this的指向正确,我们通常会写很多代码来绑定this,如果忘记绑定的话,就有会各种bug。绑定this方法:
1.this.handleClick = this.handleClick.bind(this);
2.<button onClick={(e) => this.handleClick(e)}>
Click me
</button>
于是为了解决以上问题,React Hook就被提出来了
React Hook例子
import { useState } from 'React';
function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
我们再来看看不用React Hook的话,如何实现
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}
可以看到,在React Hook中,class Example组件变成了函数式组件,但是这个函数式组件却拥有的自己的状态,同时还可以更新自身的状态。这一切都得益于useState这个Hook,useState 会返回一对值:当前状态和一个让你更新它的函数,你可以在事件处理函数中或其他一些地方调用这个函数。它类似 class 组件的 this.setState,但是它不会把新的 state 和旧的 state 进行合并。
ReactHook基本概念
Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性
从官网的这句话中,我们可以明确的知道,Hook增加了函数式组件中state的使用,在之前函数式组件是无法拥有自己的状态,只能通过props以及context来渲染自己的UI,而在业务逻辑中,有些场景必须要使用到state,那么我们就只能将函数式组件定义为class组件。而现在通过Hook,我们可以轻松的在函数式组件中维护我们的状态,不需要更改为class组件。
React Hooks要解决的问题是状态共享,这里的状态共享是指共享状态逻辑复用,并不是指数据之间的共享。我们知道在React Hooks之前,解决状态逻辑复用问题,我们通常使用higher-order components和render-props,那么既然已经有了这两种解决方案,为什么React开发者还要引入React Hook?对于higher-order components和render-props,React Hook的优势在哪?
React Hook动机
React Hook是官网提出的又一种全新的解决方案,我们先看一下React Hook提出的动机
下面说说我对这三个动机的理解:
在组件之间复用状态逻辑很难
在之前,我们通过高阶组件(Higher-Order Components)和渲染属性(Render Props)来解决状态逻辑复用困难的问题。很多库都使用这些模式来复用状态逻辑,比如我们常用redux、React Router。高阶组件、渲染属性都是通过组合来一层层的嵌套共用组件,这会大大增加我们代码的层级关系,导致层级的嵌套过于夸张。从React的devtool我们可以清楚的看到,使用这两种模式导致的层级嵌套程度
render Props
高阶组件

对于高阶组件来说,如果你没有对组件手动设置 name/displayName,就会遇到更严重的问题,那就是一个个匿名组件嵌套。毕竟上面 render props 的嵌套至少能知道组件名。
复杂组件变得难以理解
在不断变化的业务需求中,组件逐渐会被状态逻辑以及副作用充斥,每个生命周期常常会包含一些不相关的逻辑。我们写代码通常都依据函数的单一原则,一个函数一般只处理一件事,但在生命周期钩子函数中通常会同时做很多事情。比如,在我们需要在componentDidMount中发起ajax请求获取数据,同时有时候也会把事件绑定写在此生命周期中,甚至有时候需要在componentWillReceiveProps中对数据进行跟componentDidMount一样的处理。
难以理解的class
个人觉得使用class组件这种还是可以的,只要了解了class的this指向绑定问题,其实上手的难度不大。大家要理解,这并不是 React 特有的行为;这其实与 JavaScript 函数工作原理有关。所以只要了解好JS函数工作原理,其实this绑定都不是事。只是有时候为了保证this的指向正确,我们通常会写很多代码来绑定this,如果忘记绑定的话,就有会各种bug。绑定this方法:
于是为了解决以上问题,React Hook就被提出来了
React Hook例子
我们再来看看不用React Hook的话,如何实现
可以看到,在React Hook中,class Example组件变成了函数式组件,但是这个函数式组件却拥有的自己的状态,同时还可以更新自身的状态。这一切都得益于useState这个Hook,useState 会返回一对值:当前状态和一个让你更新它的函数,你可以在事件处理函数中或其他一些地方调用这个函数。它类似 class 组件的 this.setState,但是它不会把新的 state 和旧的 state 进行合并。