对React Hook基本了解

React Hook及自定义Hook 基本介绍

1.什么是Hook

Hook 是特殊的函数,只在 React渲染时有效。它们能让你 "hook" 到不同的 React 特性中去。我们可以通过hook把需要的状态、副作用方法钩进来,放在函数内部使用。让原本呆板的react函数拥有状态和生命周期。

2.useState 让函数拥有内部状态

组件通常需要根据交互更改屏幕上显示的内容。输入表单应该更新输入字段,当点击轮播图"下一个"应该更改显示的图片,或者点击一个按钮使一个显示的数字加一,都要使用到useState。

javascript 复制代码
import { useState } from 'react'
​
// 状态:随着交互变化的数据
function App() {
    const [count, setCount] = useState(0)
    const handleClick = () => {
        setCount(count + 1)  // 把函数重新走一遍 有记忆功能 每次走一遍之后修改count的内容
    }
    return (
        <>
            <button onClick={handleClick}>点击</button>
            {count}
        </>
    )
}
​
export default App
​

count是一个state变量,setCount是对应的setter函数,[..,..]为数组结构,允许从数组中读取值,useState的唯一参数是state变量的初始值。在这个例子中,count的变量是0。

State是隔离且私有的,如果同一个组件被调用两次,两个副本之间是相互隔离的。

State是一张快照 ,当状态放生更新时,编译器会对多次状态修改进行自动批处理 (React会等到事件处理函数中的所有代码都运行完毕之后再处理state更新,队列都执行完毕后,在进行UI更新),本例子中的count在按钮点击之后不会递增三次,由于快照尽管你调用了三次setCount(count + 1),但在这次渲染的事件处理函数中 number 会一直是0

javascript 复制代码
import { useState } from 'react'
​
function App() {
    let num = 0
    const [count, setCount] = useState(0) 
    const handleClick = () => {
        setCount(count + 1) //0 + 1
        setCount(count + 1) //0 + 1
        setCount(count + 1) //0 + 1
        console.log(count) 
    }
    console.log(count)
    return (
        <>
            <button onClick={handleClick}>点击</button>
            {count} {/* 渲染的是最后一次的结果 */}
        </>
    )
}
​
export default App

3.useEffect 让函数可以执行副作用

函数副作用是指函数在正常工作任务之外对外部环境所施加的影响。具体地说,函数副作用是指函数被调用,完成了函数既定的计算任务,但同时因为访问了外部数据,尤其是因为对外部数据进行了写操作,从而一定程度地改变了系统环境。函数的副作用也有可能是发生在函数运行期间,由于对外部数据的改变,导致了同步运行的外部函数受到影响。

javascript 复制代码
import { useEffect, useState } from 'react' //声明
​
function App() {
    const [count, setCount] = useState(0)
    const handleClick = () => {
        setCount(count + 1)
    }
    useEffect(() => {
        console.log(count)
    }, [count]) //count依赖项,只有count改变的时候才会触发
    //当空数组的时候只有初始的时候会触发,更新的时候不会触发
    useEffect(() => {
        console.log(count)
    }, [])
​
    return (
        <>
            <button onClick={handleClick}>点击</button>
            {count}
        </>
    )
}
​
export default App
​

useEffect 触发时机:jsx渲染完毕之后

useEffect 参数分为三种:

1.无参数useEffect(() => {console.log(count)}) 初始时触发一次 当状态发生更新时再触发

2.空数组参数useEffect(() => {console.log(count)}, []) 只有初始的时候会触发 更新的时候不会触发

3.依赖项useEffect(() => {console.log(count)}, [count]) 初始时触发一次 当依赖项发生改变时再触发

4.useContext 让函数可以深层传递参数

Context允许父组件向其下层无论多深的任何组件提供信息,而无需通过peops显示传递

javascript 复制代码
import { createContext, useContext, useState } from 'react'
​
const Context = createContext(0)
​
function App() {
    const [count, setCount] = useState(0)
    const handleClick = () => {
        setCount(count + 1)
    }
    return (
        <>
            <div>hello App</div>
            <button onClick={handleClick}>点击</button>
            <Context.Provider value={count}>
                {/* 需要传递的参数 value 传入的参数可以是任何数据类型 */}
                <Head />
            </Context.Provider>
        </>
    )
}
function Head() {
    return (
        <>
            <div>hello Head</div>
            <Title />
        </>
    )
}
function Title() {
    const value = useContext(Context) //在需要使用的组件中拿到数据
    return (
        <>
            <div>hello Title</div>
            {value}
        </>
    )
}
​
export default App
​

createContext(0) 括号中的0为初始值,当没有传递参数时得到的就是默认值

Countext可以传递随着状态发生改变的值

5.useRef 可通过ref操作DOM

javascript 复制代码
function App() {
    const [count, setCount] = useState(0)
    let num = useRef(0) 
    const handleClick = () => {
        // 更行数据之后 函数回重新渲染 num会使用当前作用域下的值0 所以每次运行之后都是1 为了使num具有记忆功能 引入ref
        setCount(count + 1)
        num.current++
        console.log(num.current)
    }
    return (
        <>
            <button onClick={handleClick}>点击</button>
            {count}
        </>
    )
}

你可以用 ref.current 属性访问该 ref 的当前值

ref再更改时不会触发重新渲染。 设置 state 会重新渲染组件,更改ref 不会!

可以在渲染过程之外修改和更新current的值 ,而对于state,只能使用state设置函数来修改state变量,从而排队重新渲染。可以把currentstate搭配使用,这样就可以渲染出current,如果只用ref则不能实现current修改后直接渲染出来。

javascript 复制代码
//通过ref操作DOM
import { forwardRef, useRef, useState } from 'react'
​
//当组件添加ref属性的时候,需要forwardRef进行转发,forwardRef让你的组件通过ref向父组件公开DOM节点
​
const MyInput = forwardRef(function MyInput( ref) {
    return (
        <>
            <input type="text" ref={ref} />
        </>
    )
})
​
function App() {
    let ref = useRef(null)
    const handleClick = () => {
        ref.current.focus()
        ref.current.style.background = 'yellow'
        ref.current.value='123'
    }
    return (
        <>
            <button onClick={handleClick}>点击</button>
            <MyInput ref={ref}/>
        </>
    )
}
​
export default App
​

由于 React 会自动处理更新DOM以匹配你的渲染输出,因此你在组件中通常不需要操作DOM。但是,有时你可能需要访问由 React管理的 DOM 元素 ------ 例如,让一个节点获得焦点、滚动到它或测量它的尺寸和位置。在React 中没有内置的方法来做这些事情,所以你需要一个指向 DOM节点的 ref来实现。

当组件添加ref属性的时候,需要forwardRef进行转发,forwardRef让你的组件通过ref向父组件公开DOM节点

6.什么是自定义HOOK

自定义hook是一个函数,函数内部可以调用其他hook函数,且以use开头命名,主要作用是对逻辑功能进行封装处理,达到一种复用能力

手动实现显示鼠标坐标的自定义hook

javascript 复制代码
import { useEffect, useState } from 'react'
​
//实现一个实时获取鼠标的自定义Hook
function useMouse() {
    const [state, setState] = useState({
        pageX: NaN,
        pageY: NaN,
    })
    useEffect(() => {
        function move(e) {
            setState({
                pageX: e.pageX,
                pageY: e.pageY,
            })
        }
        // 创建事件
        document.addEventListener('mousemove', move)
        return () => {
            //清理工作 删除事件
            document.removeEventListener('mousemove', move)
        }
    }, [])
​
    return state
}
function App() {
    const mouse = useMouse()
    return (
        <>
            <div>
                {mouse.pageX} {mouse.pageY}
            </div>
        </>
    )
}
​
export default App

第三方Hooks:ahooks react-use

相关推荐
~甲壳虫几秒前
说说webpack中常见的Plugin?解决了什么问题?
前端·webpack·node.js
光影少年20 分钟前
vue2与vue3的全局通信插件,如何实现自定义的插件
前端·javascript·vue.js
As977_21 分钟前
前端学习Day12 CSS盒子的定位(相对定位篇“附练习”)
前端·css·学习
susu108301891123 分钟前
vue3 css的样式如果background没有,如何覆盖有background的样式
前端·css
Ocean☾24 分钟前
前端基础-html-注册界面
前端·算法·html
Rattenking25 分钟前
React 源码学习01 ---- React.Children.map 的实现与应用
javascript·学习·react.js
Dragon Wu27 分钟前
前端 Canvas 绘画 总结
前端
CodeToGym31 分钟前
Webpack性能优化指南:从构建到部署的全方位策略
前端·webpack·性能优化
~甲壳虫32 分钟前
说说webpack中常见的Loader?解决了什么问题?
前端·webpack·node.js
~甲壳虫36 分钟前
说说webpack proxy工作原理?为什么能解决跨域
前端·webpack·node.js