react 自定义hook与高阶组件的区别

useState:

现在有了hook,也能在function组件中管理数据状态了。

import React, { useState } from 'react'
const Counter = () => {
    // 定义需要管理状态的数据,在useState()中设置默认值
    const [count, setCount] = useState(0)
    return (
        <button onClick={() => {setCount(count + 1)}}>已点击{count}</button>
    )
}

注意:

class组件中,state更新数据的方式是合并,也就是说只修改了我们要修改的那一项,例如:

constructor(props) {
        super(props);
        this.state = { count: 0, name: 'bob' };
        this.handleClick = this.handleClick.bind(this);
    }

handleClick() {
        this.setState((state) => {
            return {count: state.count + 1}
        })
    }
    // 运行一次后的state结果是{ count: 1, name: 'bob' }

但在useState中,更新数据的方式是替换

const [someOne, setSomeOne] = useState({ count: 0, name: 'frank' })
const handleClick = () => {
        setSomeOne({ count: someOne.count + 1 })
    }
// 此时someOne的结果是{count: 1}

useEffect:

//会在每次页面完成渲染或更新数据后执行。
import React, { useState, useEffect } from 'react'

const Counter = () => {
    const [count, setCount] = useState(0)
    useEffect(() => {
        document.title = '已点击' + count + '次'
        // 此时title会随用户的点击而改变
    })
    return (
        <button onClick={() => {setCount(count + 1)}}>已点击{count}次</button>
    )
}

/***************************************/

useEffect还有第二个参数,通过监听传入的参数来决定是否执行这个useEffect

import React, { useState, useEffect } from 'react'

const Counter = () => {
    const [count, setCount] = useState(0)
    const [num, setNum] = useState(0)
    useEffect(() => {
        console.log('count改变了')
    },[count])
    return (
        <div>
            <button onClick={() => {setCount(count + 1)}}>已点击{count}次</button>
            <button onClick={() => {setNum(num + 1)}}>已点击{num}次</button>
        </div>
    )
}
// 此时只有第一个按钮被点击时,控制台才会打印出count改变了

如果你希望只在页面渲染完成的时候执行(数据更新后不执行),你可以将第二个参数设置成[],这样useEffect就不依赖任何值了,只会在页面渲染完成后执行。
设置成[],一般用来做初始化调用api接口。
相当于componentDidMount


以上的useEffect都是不用清除的useEffect,但有些情况下我们还是需要清除useEffect的,例如为某个元素添加事件:

const Counter = () => {
  const [count, setCount] = useState(0)
  useEffect(() => {
    // 在页面更新后添加事件
    const updateMouse = (e) => {
      console.log('ok')
      setCount(count + 1)
    }
    document.addEventListener('click', updateMouse)
  })
  return (
    <div>{count}</div>
  )
}
// 表面上你看到的页面没什么问题,但是你可以打开控制台看下每点击一次ok的打印次数。
// 应该是1 3 6 12

const Counter = () => {
  const [count, setCount] = useState(0)
  useEffect(() => {
    // 在页面更新后添加事件
    const add = (e) => {
      console.log('ok')
      setCount(count + 1)
    }
    document.addEventListener('click', add)
    //在这里加入return函数 
      相当于componentWillUnmount
    return () => {
        document.removeEventListener('click', add)
    }
  })
  return (
    <div>{count}</div>
  )
}


此时,再去看控制台ok的次数就会正常显示,useEffect里的return会在每次新的useEffect执行之前执行,这就做到了清除useEffect了。

 

自定义Hook

现在有这样一种需求,我们需要获取鼠标当前的位置坐标,但是不仅仅是一个页面需要,
此时我们就可以用到自定义Hook了。 (实际上就是相当于函数而已)
import React, { useState, useEffect } from 'react'
//use开头
const useMousePosition = () => {
    const [position, setPosition] = useState({x: 0, y: 0 })
    useEffect(() => {
        const updateMouse = (e) => {
            setPosition({ x: e.clientX, y: e.clientY })
        }
        document.addEventListener('mousemove', updateMouse)
        return () => {
            document.removeEventListener('mousemove', updateMouse)
        }
    })
    return position
}

export default useMousePosition

之后在需要的地方引入然后调用即可

import React from 'react'
import useMousePosition from './useMousePosition'

function App() {
    const position = useMousePosition()
    return (
        <div>
            <div>x: {position.x}</div>
            <div>y: {position.y}</div>
        </div>
    )
}

自定义hook不仅可以这么用,还可以根据情况替换掉高阶组件。

高阶组件实际上就是把一个组件当参数传入,再返回一个新的组件出来。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值