React hooks使用规则和作用

 更新时间:2023年03月14日 08:52:55   作者:旺仔好吃糖  
这篇文章主要介绍了react hooks实现原理,文中给大家介绍了useState dispatch 函数如何与其使用的 Function Component 进行绑定,节后实例代码给大家介绍的非常详细,需要的朋友可以参考下

使用hooks理由:

  • 高阶组件为了复用,导致代码层级复杂
  • 生命周期的复杂
  • 写成functional组件,无状态组件,因为需要状态,又改成了class,成本高

hooks使用规则

  • 只能在函数最外层调用 Hook。不要在循环、条件判断或者子函数中调用。
  • 只能在 React 的函数组件中调用 Hook。不要在其他 JavaScript 函数中调用。(还有一个地方可以调用 Hook —— 就是自定义的 Hook 中

useState(保存组件状态)

语法:

//导入 useState
import React,{useState}from 'react'
..........................................
const [state,setState] = useState(initialState)

内容

  • 返回一个state,以及修改state的函数,在初始渲染期间,返回的状态state与传入的第一个参数值 initialState值相同
  • setState函数用于更新 state。它接收一个新的参数,并将组件的一次重新渲染加入队列。
  • 可以在一个组件中多次使用

修改state

//setState(newState)
setState('123')

useEffect(处理副作用)

使用useEffect

在函数组件中,要知道这个组件现在处在那个生命周期,比较麻烦,甚至有点无从下手,这时候我们就可以使用hook中的useEffect()

注意:

  • Function Component不存在生命周期,所以不要把Class Component 的生命周期概念搬过来试图对号入座
  • 默认情况下,useEffect会在第一次渲染之后和每次更新之前都会执行

语法

useEffect(()=>{
    .........
},[依赖;空数组,表示不依赖])
//依赖:在useEffect函数中使用的状态

注意:如果明明使用了某个变量,却没有申明在依赖中,那么当依赖的变量改变时,useEffect也不会再次执行,控制台会报警告

清除effect

组件卸载时需要清除effect创建的如计时器或请阅等资源,useEffect函数需要返回一个清除函数即可

useEffect(()=>{
   //组件挂载创建计时器
    var timer = setInterval(()=>{
            console.log('111');
   },1000)
    ........
   return ()=>{
       //清除计时器  若无依赖时组件销毁
       clearInterval(timer)
   } 
},[])

useCallback(记忆函数)

防止因为组件重新渲染,导致方法被重新创建,起到缓存作用,只有第二个参数变化了,才能重新声明一次

语法

var handleClick = useCallback(
    ()=>{
        console.log(name)
    },
    [name]
)
<button onClick={()=>handleClick()}>hello</button>

内容

  • 当依赖不改变时,方法不会被重建;当只有当依赖(name)发生改变时,这个函数才会被重新创建
  • 如果传入空数组,name就是第一次创建后就被缓存,name后期即使改变,拿到的还是老的name
  • 如果不传第二个参数,每次都会被重新声明一次,拿到的就是最新的name

useMemo(记忆组件)

useCallback常用记忆事件函数,生成记忆后的事件函数并传递给子组件使用。而useMemo更适合经过函数计算得到一个确定的值,比如记忆组件

useCallback的功能完全可以由useMemo取代

useMemo(() => fn,inputs)

区别:useCallback不会执行第一个参数函数,而是将他返回给你,而useMemo会执行第一个函数并且将函数执行结果返回给你

useRef(保存引用值)

//相当于React.createRef()
const mytext = useRef()
................
 <input ref={mytext}></input>

useContext

语法

const GlobalContext = React.createContext()//创建context对象

内容

🌋🌋🌋收一个context对象(React.createContext的返回值)并返回该context的当前值。当前的context值由上次组件中距离当前组件最近的 的value *<GlobalContext.Provider> *的value prop决定

实例

//创建context对象
const GlobalContext = React.createContext()//创建context对象
..................................
//GlobalContext.Provider的value
 <GlobalContext.Provider value={{
           "call":"打电话"
}}>
//GlobalContext.Consumer通过context获得value
Function FilmDetail(){
    const value = useContext(GlobalContext)
    return(
            <div className="filmDetail">
                detail-{value.info}
            </div>
       )
}

useReducer

可以在外部管理状态,只能在函数组件中调用

语法

定义useReducer

组件内部:
//intialState初始状态值 state拿到状态值,dispatch改变状态
const [state,dispatch] = useReducer(reducer,intialState)

定义在外部处理函数

//处理函数
const reducer=(prevState,action)=>{
    //prevState--老的状态
    //action--dispatch内对象
    return prevState/newState
}

🍧🍧🍧return 出新状态 组件内部即可通过 state获得全新的状态

定义在外部的状态

组件外部:
//定义在外部的状态
const intialState={
    //放入初始状态值
}

useContext与useReducer实现跨组件传值

实现的效果

在App父组件中使用useReducter在外部管理所有子组件的状态,使用useContext将dispatch处理函数以及initailState状态传递给子组件(Child1,Child2,Child3),Child1使用useContext获得传入的dispatch,Child2、Child3获得传入的state,此时Child1触发dispatch()来改变state的值(a、b),而后Child2、Child3将获得Child1修改后的最新的state值

引入useContext和useReducer

import React,{useReducer,useContext}from 'react'
//创建context
const GlobalContext = React.createContext()//创建context对象

useReducer实现使用外部状态管理数据,useContext实现组件间传数据

定义外部状态及处理函数

const initailState = {
    a:'1111',
    b:'1111'
}
const reducer = (prevState,action)=>{
    let newState = {...prevState}
    switch(action.type){
        case "change-a":
            newState.a = action.value
            return newState
        case "change-b":
            newState.b = action.value
            return newState
        default:
            return prevState
    }
}

action为接收到的diapatch函数,switch语句是根据dispatch中的type值的不同,修改a、b(不能直接修改)

父组件

export default function App() {
  const [state,dispatch] = useReducer(reducer,initailState)
  return (
    <GlobalContext.Provider value={
        {
            state,
            dispatch
        }
    }>
        <div>
            <Child1></Child1>
            <Child2></Child2>
            <Child3></Child3>
        </div>
    </GlobalContext.Provider>
  )
}

Child1获得dispatch,Child2、Child3获得state

Child1修改state

function Child1(){
    const {dispatch} = useContext(GlobalContext)
    return(
        <div style={{background:'gray'}}>
            <button onClick={()=>{
                dispatch({
                    type:"change-a",
                    value:'22222'
                })
            }}>改变a</button>
            <button onClick={()=>{
                dispatch({
                    type:"change-b",
                    value:'33333'
                })
            }}>改变b</button>
        </div>
    )
}

触发dispatch函数,传入reducer,实现间接修改state

Child2、Child3获得最新的state

function Child2(){
    const {state} = useContext(GlobalContext)
    return(
        <div style={{background:'yellow'}}>
            child2-{state.a}
        </div>
    )
}
function Child3(){
    const {state} = useContext(GlobalContext)
    return(
        <div style={{background:'blue'}}>
            child3-{state.b}
        </div>
    )
}

自定义hooks

当我们想在两个函数之间共享逻辑时,我们会把它提取到第三个函数中

只抽出逻辑,不改变渲染页面

​ 注意:必须以use开头,不遵循的话,由于无法判断某个函数是否包含对其内部Hook的调用,React将无法自动检查你的Hook是否违反了Hook的规则

到此这篇关于React hooks使用规则和作用的文章就介绍到这了,更多相关React hooks内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • React中父子组件通信详解

    React中父子组件通信详解

    这篇文章主要介绍了React中父子组件通信详解,在父组件中,为子组件添加属性数据,即可实现父组件向子组件通信,文章通过围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-08-08
  • react.js组件实现拖拽复制和可排序的示例代码

    react.js组件实现拖拽复制和可排序的示例代码

    这篇文章主要介绍了react.js组件实现拖拽复制和可排序的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • 利用React高阶组件实现一个面包屑导航的示例

    利用React高阶组件实现一个面包屑导航的示例

    这篇文章主要介绍了利用React高阶组件实现一个面包屑导航的示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • React路由拦截模式及withRouter示例详解

    React路由拦截模式及withRouter示例详解

    这篇文章主要为大家介绍了React路由拦截模式及withRouter示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • ChatGLM 集成LangChain工具详解

    ChatGLM 集成LangChain工具详解

    这篇文章主要为大家介绍了Svelte和React框架使用比较,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • 一起来了解React的Hook

    一起来了解React的Hook

    这篇文章主要为大家详细介绍了React的Hook,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • React语法中设置TS校验规则的步骤详解

    React语法中设置TS校验规则的步骤详解

    这篇文章主要给大家介绍了React语法中如何设置TS校验规则,文中有详细的代码示例供大家参考,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2023-10-10
  • ReactNative之键盘Keyboard的弹出与消失示例

    ReactNative之键盘Keyboard的弹出与消失示例

    本篇文章主要介绍了ReactNative之键盘Keyboard的弹出与消失示例,具有一定的参考价值,有兴趣的可以了解一下
    2017-07-07
  • 详解React-Todos入门例子

    详解React-Todos入门例子

    本篇文章主要介绍了React-Todos入门例子,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-11-11
  • react native之ScrollView下拉刷新效果

    react native之ScrollView下拉刷新效果

    这篇文章主要为大家详细介绍了react native之ScrollView下拉刷新效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09

最新评论