hooks的出现

2022-02-21 22:14阅读 129

Hook是 React16.8 的新增特性, 它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。

以此来提高代码的复用性,

关于代码的复用的解决方案 从最开始的 Mixin 到 HOC 到 Render Prop,再到至今的 Custom Hook。

Mixin在使用上存在一些弊端,

复用的代码的相关依赖都是隐式的,不好追踪的,结果也是不好预测的,并且存在命名冲突覆盖的问题,后面被React不推荐使用

var sentryMixin = {
    this.startTime = null
    componentDidMount() {
        this.startTime = new Date()
    },
    componentWillUnmount() {
        const endTime = new Date()
        console.log(endTime - this.startTime)
    }
}
var UserPage = React.createClass({
    mixins: [sentryMixin],
    render() {
       return <div>UserPage Component</div>
    }
})

HOC 本质上是一个函数,接收Component 为参数, 返回一个新的组件

组件可分为容器组件(container)和展示组件(component)

容器组件保存状态和事件,展示组件根据父级传入的状态和事件用来渲染

const withSentry = (Component) => {
    class HOCComponent extends React.Component {
        componentDidMount() {
            this.startTime = new Date()
        }
        componentWillUnmount() {
            const endTime = new Date()
            console.log(endTime - startTime)
        }
        render() {
            return <Component />
        }
    }
    
    return <HOCComponent />
    
}

class UserPage extends React.Component {
    render() {
        return <div>UserPage</div>
    }
}

withSentry(UserPage)

至今的就是 React Hook了

函数组件可以实现代码复用, 但是函数没有状态,也无法复用。

hook的出现就是为了解决复用函数组件时不能复用状态的问题,hook的核心是闭包,

hook只能在函数的顶层使用,不能在判断、循环语句,jsx中使用

  • useState

    最基础的hook,状态生成器,函数接收一个参数为默认状态值。

    返回一个数组 [state, setState], 既状态值和修改状态的方法

    例如:

    const [foo, setFoo] = useState('hello')
    console.log(foo) // hello
    setFoo('world') 
    console.log(foo) // world
    
  • userEffect

    接收两个参数 effectCallback 和 dept?

    effectCallback为 当 dept 发生变化时的回调函数,当组件卸载时会执行 effectCallback()(),可利用此特性移除一些副作用函数,比如监听事件,定时器

    dept 为需要监听的值,这个值的类型为数组或undefined,当为undefined时,则每次函数执行都会调用,当为[]则表示不监听任何值,只会执行一次,利用此特性

    注意dept的值不能为复杂类型的普通值,可以是简单类型的值或者经过缓存的状态值,因为,复杂类型的值和闭包中保存的值来比较,由于内存地址不同是不等的,

    此hook没有返回值

    示例

    const Counter = () => {
        useEffect(() => {
            const timer = setInterval(() => {
                console.log('hi!')
            },1000)
            
            return () => clearInterval(timer)
        },[])
    }
    

    加上状态值

    const Counter = () => {
        const [count, setCount] = useState(0)
        useEffect(() => {
            const timer = setInterval(() => {
                console.log(count)
                setCount(count + 1)
            },1000)
            
            return () => clearInterval(timer)
        },[])
    }
    
标签
标签
标签