Hooks的使用

类组件和函数组件的区别

类组件和hooks是两个概念,hooks只是一个工具集,用来增强函数组件的功能。真正对比的是类组件和函数组件的差异。

代码风格上的差异

类组件中有:

  • 是一个class类,需要继承
  • 可以直接定义内部的state状态
  • 组件内有生命周期钩子
  • 可以用this获取组件的实例

    应用数据props不同

    两类组件之间最大的区别,用https://overreacted.io/zh-hans/how-are-function-components-different-from-classes/表示“函数式组件捕获了渲染所用的值(props),props会在函数组件中形成闭包”
    网站所用的实例代码:

    函数组件

    1. function ProfilePage(props) {
    2. const showMessage = () => {
    3. alert('Followed ' + props.user);
    4. };
    5. const handleClick = () => {
    6. setTimeout(showMessage, 3000);
    7. };
    8. return (
    9. <button onClick={handleClick}>Follow</button>
    10. );
    11. }

    类组件

    ```javascript class ProfilePage extends React.Component { showMessage = () => { alert(‘Followed ‘ + this.props.user); };

    handleClick = () => { setTimeout(this.showMessage, 3000); };

    render() { return ; } }

  1. <a name="CwDa3"></a>
  2. ### 对比不同
  3. 用类组件和函数组件实现同样的关注逻辑,两种组件都会接受props.user的属性,点击关注按钮3秒后会弹出一条信息。如果一开始传入的是{user: "帅哥"},然后在3秒内切换prop的值变化成{user: "美女"}。类组件和函数组件的结果会不同:
  4. ```javascript
  5. // 函数组件会打印
  6. '关注帅哥'
  7. // 类组件会打印
  8. '关注美女'

线上代码演示:https://codesandbox.io/s/duibileizujianhehanshuzujian-uh8yf
在类组件中props是不变的,但是this永远是变化的。当有数据更新,props和state会同步更新。

解决类props的实时更新

第一种办法,在调用props之前读取this.props,然后将他们显示的传递到异步回调

  1. class ProfilePage extends React.Component {
  2. showMessage = (user) => {
  3. alert('关注'+ user)
  4. };
  5. handleClick = ()=>{
  6. const {user} = this.props;
  7. setTimeout(()=> this.showMessage(user), 3000)
  8. };
  9. return() {
  10. return <button onClick={this.handleClick}>关注</button>
  11. }
  12. }

这个方法生效,但是会让代码变的冗长,难以维护,容易出错。
另一种方法:把事件写在render函数中

  1. class ProfilePage extends React.Component {
  2. render() {
  3. const props = this.props;
  4. const showMessage = () => {
  5. alert('成功关注 ' + props.user);
  6. };
  7. const handleClick = () => {
  8. setTimeout(showMessage, 3000);
  9. };
  10. return <button onClick={handleClick}>关注</button>;
  11. }
  12. }

这个方法其实函数组件的原理,props变化之后,组件虽然重新渲染了,但是老的props通过闭包保存了下来,然后被打印出来。

为什么要使用函数组件+hooks

对比类组件的缺点,函数组件+hooks有以下优点:

  1. 函数组件写法更轻量灵活
    1. 在函数组件中,我们不需要去继承一个class对象,不需要记忆那些生命周期,不需要固定的把数据定义在state中。
    2. 函数作为js中的一等公民,函数式编程方式可以让我们可以更加灵活的去组织代码。
  2. 类组件存在缺陷
    1. 在React中,如果我们定义一个方法,我们必须使用bind或者箭头函数去约束这个方法的this的作用域。
    2. 如果需要一个只跟着视图触发事件时的数据显示,不能直接使用props或state
  3. hooks更符合react的基本理念
    1. 在一次渲染中,props和state是保持不变

但是hooks并不能完全替代类组件,hooks很多方法,用来增强函数组件的功能。如useState/useEffect/useRef/useContext/useMemo/useReducer