React Hooks

1.Hooks是什么?

  • Hooks 是 **React v16.8** 中的新增功能 
  • 作用:为**函数组件**提供状态、生命周期等原本 class 组件中提供的 React 功能 
  • 注意:**Hooks 只能在函数组件中使用**,自此,函数组件成为 React 的新宠儿 

    有了 Hooks 以后,不能再把**函数组件**称为~~无状态组件~~了,因为 Hooks 为函数组件提供了状态


2.为什么要有Hooks

  • 组件的状态逻辑复用问题
  • class 组件自身的问题:(选择类组件还是函数组件;类组件中this指向问题;类组件不利于代码压缩和优化)

3.useState----基本使用

  • `useState`使用场景:当你想要在**函数组件中,使用组件状态时**,就要使用 **useState** 
  • `useState`作用:为函数组件提供状态(state)

 步骤:

  1.  导入 `useState` hook(import  {useState} from 'react')
  2.  调用 `useState` 函数,并传入状态的初始值(useState(0) 0是默认值,可以写任意数据类型)
  3.  从 `useState` 函数的返回值中,拿到状态和修改状态的函数(函数返回一个数组,两个值(默认值,修改状态的函数))
  4.  在 JSX 中展示状态
  5.  在按钮的点击事件中调用修改状态的函数,来更新状态

 代码小案例


import React,{useState} from 'react'

export default function useState用法() {
    // 语法:useState(状态数据默认值)
    const state=useState(0)
    const state2=useState({name:'cc',age:18})
    console.log(state);
    console.log(state2);
    // count表示默认值;setCount表示方法,用来修改值
    const count=state[0]
    const setCount=state[1]

  return (
   <div>
    <ul>
        <li>{count}</li>
        <li onClick={()=>{setCount(count+1)}}>add</li>
        <li></li>
    </ul>
   </div>
  )
}

 效果:点击add,count加1


4.useState----使用数组解构简化

  代码小案例


import React,{useState} from 'react'

export default function useState用法() {
    // 语法:useState(状态数据默认值)
    // 1.简单类型
    const [count,setCount]=useState(0)
    const [isShow,setShow]=useState(true)
    // 2.复杂类型
    const [obj,setObj]=useState({name:'cc',age:18})
    const [arr,setArr]=useState([1,2,3])
  return (
   <div>
    <ul>
        <li>{count}</li>
        <li>
          <button onClick={()=>{setCount(count+1)}}>add</button>
       </li>
        <li>
            {isShow?'开':'关'}
        </li>
        <li>
            <button onClick={()=>{setShow(!isShow)}}>开关</button>
        </li>
        <li>姓名:{obj.name},年龄:{obj.age}</li>
        <li>
            <button onClick={()=>{setObj({...obj,name:'小魔仙'})}}>变变变</button>
        </li>
    </ul>
    <hr/>
    {/* 数组 */}
    <ul>
        {
            arr.map(item=>{
                return <li key={item}>{item}</li>
            })
        }
        <button onClick={()=>{setArr([...arr,Math.random()*1000])}}>数组添加</button>
    </ul>
   </div>
  )
}


5.useState-------注意事项

  • **React Hooks 只能直接出现在 函数组件 中* 
  •  **React Hooks不能嵌套在 if/for/其他函数 中

6.useEffect---------基本使用

  • 目标:**能够在函数组件中操作DOM(处理副作用) 
  • 使用场景:当你想要在函数组件中,处理副作用(side effect)时就要使用 useEffect Hook 
  • 作用:处理函数组件中的一些副作用(side effect)
  • 注意:在实际开发中,副作用是不可避免的。因此,react 专门提供了 **useEffect** Hook **来处理函数组件中的副作用

   语法:

  • 参数:回调函数(称为 **effect**),就是**在该函数中写副作用代码
  • 执行时机:该 effect 会在组件第一次渲染以及每次组件更新后执行
  • 相当于 componentDidMount + componentDidUpdate
import { useEffect } from 'react'

useEffect(function effect() {
  document.title = `当前已点击 ${count} 次`
})

useEffect(() => {
  document.title = `当前已点击 ${count} 次`
})

   页面标题更改,小案例


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

export default function useEffect用法() {
    const [count,setCount]=useState(10000)

    // 需求:每次count变化,html页面的title随着变化
    // 语法:useEffect(callback函数)
    // 执行:相当于componentDidMount+componentDidUpdate(2合1)
    // 1.组件第一次渲染,会执行一次callback函数
    // 2.状态数据变化,callback函数会再次执行
    useEffect(()=>{
        console.log('useEffect');
        // 操作DOM(副作用)
        document.title=`ha ${count}`
    }
   )
  return (
   <div>
    <ul>
        <li>{count}</li>
        <li>
            <button onClick={()=>setCount(count+10000)}>add</button>
        </li>
    </ul>
   </div>
  )
}


  7.useEffect-------依赖

  • 目标:**能够设置 useEffect 的依赖只在 count 变化时执行相应的 effect 
  • 问题:如果组件中有另外一个状态,另一个状态更新时,刚刚的 effect 回调也会执行
  • 默认情况:只要状态发生更新 useEffect 的 effect 回调就会执行
  • 性能优化:**跳过不必要的执行,只在 count 变化时,才执行相应的 effect
  • 语法:(1.第二个参数:可选,也可以传一个数组,数组中的元素可以成为依赖项(deps);2.该示例中表示:只有当 count 改变时,才会重新执行该 effect)

 案例


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

export default function useEffect用法() {
    const [count,setCount]=useState(10000)
    const [num,setNum]=useState(0)
    // 需求:每次count变化,html页面的title随着变化
    // 语法:useEffect(callback函数,[依赖1,依赖2,...])
    // 执行:相当于componentDidMount+componentDidUpdate(2合1)
    useEffect(()=>{
        console.log('useEffect');
        // 操作DOM(副作用)
        document.title=`ha ${count}`
    },[count]
   )
  return (
   <div>
    <ul>
        <li>{count}</li>
        <li>{num}</li>
        <li>
            <button onClick={()=>setCount(count+10000)}>add-count</button>
        </li>
         <li>
            <button onClick={()=>setNum(num+1)}>add-num</button>
        </li>
    </ul>
   </div>
  )
}


8.useEffect----------不要对依赖项撒谎

  • useEffect 回调函数(effect)中用到的数据(比如,count)就是依赖数据,就应该出现在依赖项数组中
  • 如果 useEffect 回调函数中用到了某个数据,但是,没有出现在依赖项数组中,就会导致一些 Bug 出现!
const App = () => {
  const [count, setCount] = useState(0)

  // 错误演示:
  useEffect(() => {
    document.title = '点击了' + count + '次'
  }, [])

  return (
    <div>
      <h1>计数器:{count}</h1>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </div>
  )
}

9.useEffect----------依赖是一个空数组

  •  目标:**能够设置useEffect的依赖,让组件只有在第一次渲染后会执行
  • useEffect 的第二个参数,还可以是一个空数组([]),表示只在组件第一次渲染后执行 effect
  • 使用场景:1 事件绑定 2 发送请求获取数据 等

   小案例


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

export default function useEffect空数组() {
    const [list,setList]=useState([])

    var getList=async()=>{
        var {data}=await axios.get('http://localhost:8888/list')
        console.log(data);
        setList(data)
    }
    useEffect(()=>{
        console.log('useEffect');
        getList()
    },[])
   
  return (
    <div>
        <ul>
           {list.map(item=>{
            return <li key={item.id}>{item.id}</li>
           })}
        </ul>
    </div>
  )
}


10.useEffect------清理工作

相当于:componentWillUnmount

  • 目标:**能够在组件卸载的时候清除注册的事件 
  • effect 的**返回值**是可选的,可省略。也可以返回一个**清理函数**,用来执行事件解绑等清理操作
  • 清理函数的执行时机:(1.**清理函数**会在组件卸载时以及下一次副作用回调函数调用的时候执行,用于清除上一次的副作用。2.如果依赖项为空数组,那么会在组件卸载时会执行。相当于组件的`componetWillUnmount)
    useEffect(() => {
      // 这个返回的函数,会在该组件卸载时来执行
      // 因此,可以去执行一些清理操作,比如,解绑 window 的事件、清理定时器 等
      return () => window.removeEventListener('resize', handleResize)
    }, [])

    条件:依赖项为空,useEffect中return函数


11.useEffect---------语法总结

// 1
// 触发时机:1 第一次渲染会执行 2 每次组件重新渲染都会再次执行
// componentDidMount + ComponentDidUpdate
useEffect(() => {})

// 2(使用频率最高)
// 触发时机:只在组件第一次渲染时执行
// componentDidMount
useEffect(() => {}, [])

// 3(使用频率最高)
// 触发时机:1 第一次渲染会执行 2 当 count 变化时会再次执行
// componentDidMount + componentDidUpdate(判断 count 有没有改变)
useEffect(() => {}, [count])

// 4
useEffect(() => {
  // 返回值函数的执行时机:组件卸载时
  // 在返回的函数中,清理工作
  return () => {
      // 相当于 componentWillUnmount
  }
}, [])

useEffect(() => {

  // 返回值函数的执行时机:1 组件卸载时 2 count 变化时
  // 在返回的函数中,清理工作
  return () => {}
}, [count])

12.useEffect-----发送请求

  • 目的:**能够在函数组件中通过useEffect发送ajax请求 
  • 在组件中,可以使用 useEffect Hook 来发送请求(side effect)获取数据
  • 注意:**effect 只能是一个同步函数,不能使用 async(因为如果 effect 是 async 的,此时返回值是 Promise 对象。这样的话,就无法保证清理函数被立即调用)
  • 为了使用 async/await 语法,可以在 effect 内部创建 async 函数,并调用
// 错误演示:不要给 effect 添加 async
useEffect(async () => {
  const res = await axios.get('http://xxx')
  return () => {}
}, [])

// 正确使用
useEffect(() => {
  const loadData = async () => {
    const res = await axios.get('http://xxx')
  }
  loadData()

  return () => {}
}, [])

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值