React Hooks的学习与理解(一)

2020-05-26  本文已影响0人  依然还是或者其他

前言

在使用Hooks时常常会出现一些有趣的问题,这些问题往往跟你之前的Component组件的思维有关。

Hooks与Component

Hooks的useEffect的确可以模拟部分class组件中生命周期的方法,但并不能把两者等同。因为两者本身是不同的(看起来像是一句废话)

Function组件是没有实例的,而Component组件是有实例的,这会导致在Function组件中没有办法引用和保证前一个state,而Component组件是可以的,所以Hooks添加了useRef。

可以再看下两者在渲染时的差异

Function 组件

function Example() {
  const [count, setCount] = useState(0);

  function handleAlertClick() {
    setTimeout(() => {
      alert('You clicked on: ' + count);
    }, 3000);
  }

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

Component组件

class Example extends React.Component{
  state={
    count:0
  }

  handleAlertClick=()=> {
    setTimeout(() => {
      alert('You clicked on: ' + this.state.count);
    }, 3000);
  }

  render(){
    const {count}=this.state;
    return (
      <div>
        <p>You clicked {count} times</p>
        <button onClick={() => this.setState({count:count+1})}>
          Click me
        </button>
        <button onClick={this.handleAlertClick}>
          Show alert
        </button>
      </div>
    );
  }
}

同样的操作,比如点击Click Me按钮,先点击3次,然后点击Show alert按钮,再点击Click Me按钮2次。
那么同样的操作在两者中的alert结果是不同的:

原因在于Function组件的render相当于对当前状态进行了一次快照,props、state和其他事件函数等等都是重新生成的且独立的。这不同于Component组件,Component组件的props、state和事件函数可以保存在实例上,不需要重新生成,也就是实时的。
当然上面的Function组件例子中也有涉及到闭包相关的东西。

Hooks与闭包

Function组件在使用Hooks时会产生闭包。
在查看Hooks源码后也能体现出来。

闭包的其中一个特性是可以保持一个变量的持续引用。
再加上Function组件每次render都是一次独立的快照,即重新生成的了一个全新的函数。
那么当之前的异步函数发生调用时,由于闭包的特性,还保持了对于之前的引用,所以就导致了上述例子Function组件alert出来的是3。

由于Component组件的思维模式,在Hooks的开发中,常常会导致一些问题,其他很大一部分就是由于Function的快照与闭包导致的。

参考:
1.Hook 概览——React官方文档
2.Hooks FAQ——React官方文档
3.简单聊一聊 hooks 与闭包——Limboer
4.a-complete-guide-to-useeffect——Dan Abramov

上一篇 下一篇

猜你喜欢

热点阅读