个人网站赏析,长沙网站整站优化,绍兴网站专业制作,当下最流行的营销方式react之Hooks的介绍、useState与useEffect副作用的使用 一、Hooks的基本介绍二、useState的使用2.1 简单使用2.2 数组结构简化2.3 状态的读取和修改2.3 组件的更新过程 三、useEffect的使用3.1 副作用介绍3.2 基本使用3.3 依赖3.4 不要对依赖项撒谎3.5 依赖项可以是空数组3.6 清… react之Hooks的介绍、useState与useEffect副作用的使用 一、Hooks的基本介绍二、useState的使用2.1 简单使用2.2 数组结构简化2.3 状态的读取和修改2.3 组件的更新过程 三、useEffect的使用3.1 副作用介绍3.2 基本使用3.3 依赖3.4 不要对依赖项撒谎3.5 依赖项可以是空数组3.6 清理工作3.7 useEffect的 4 种使用使用方式3.8 发送请求3.9 axios请求本地json数据 一、Hooks的基本介绍
Hooks 是 React v16.8 中的新增功能 为函数组件提供状态、生命周期等原本 class 组件中提供的 React 功能可以理解为通过 Hooks 为函数组件钩入 class 组件的特性注意Hooks 只能在函数组件中使用自此函数组件成为 React 的新宠儿可以在项目中同时使用hooks和class
二、useState的使用
2.1 简单使用
一个 Hook 就是一个特殊的函数让你在函数组件中获取状态等 React 特性useState使用场景当你想要在函数组件中使用组件状态时就要使用 useState Hook 了useState作用为函数组件提供状态state
import { useState } from reactconst Count () { // stateArray 是一个数组const stateArray useState(0)const state stateArray[0]const setState stateArray[1]return (div{/* 展示状态值 */}h1状态为{state}/h1{/* 点击按钮让状态值 1 */}button onClick{() setState(state 1)}1/button/div)
}2.2 数组结构简化
import { useState } from reactconst Count () {// 解构const [count, setCount] useState(0)return (divh1计数器{state}/h1button onClick{() setState(state 1)}1/button/div)
}2.3 状态的读取和修改
读取状态useState 提供的状态是函数内部的局部变量可以在函数内的任意位置使用
const Counter () {const [user, setUser] useState({ name: jack, age: 18 })return (divp姓名{user.name}/pp年龄{user.age}/p/div)
}修改状态 setCount(newValue) 是一个函数参数表示新的状态值 调用该函数后将使用新的状态值替换旧值修改状态后因为状态发生了改变所以该组件会重新渲染
const Counter () {const [user, setUser] useState({ name: jack, age: 18 })const onAgeAdd () {setUser({...user,age: user.age 1})}return (divp姓名{user.name}/pp年龄{user.age}/pbutton onClick{onAgeAdd}年龄1/button/div)
}修改状态的时候一定要使用新的状态替换旧的状态
2.3 组件的更新过程 函数组件使用 useState hook 后的执行过程以及状态值的变化 组件第一次渲染 1.从头开始执行该组件中的代码逻辑2.调用 useState(0) 将传入的参数作为状态初始值即03.渲染组件此时获取到的状态 count 值为 0 组件第二次渲染 1.点击按钮调用 setCount(count 1) 修改状态因为状态发生改变所以该组件会重新渲染2.组件重新渲染时会再次执行该组件中的代码逻辑3.再次调用 useState(0)此时 React 内部会拿到最新的状态值而非初始值比如该案例中最新的状态值为 14.再次渲染组件此时获取到的状态 count 值为1 useState 的初始值(参数)只会在组件第一次渲染时生效 核心代码 import { useState } from reactconst Count () {const [count, setCount] useState(0)return (divh1计数器{count}/h1button onClick{() setCount(count 1)}1/button/div)
}三、useEffect的使用
3.1 副作用介绍
内容 使用场景当你想要在函数组件中处理副作用side effect时就要使用 useEffect Hook 了 作用处理函数组件中的副作用side effect 问题副作用side effect是什么? 回答在计算机科学中如果一个函数或其他操作修改了其局部环境之外的状态变量值那么它就被称为有副作用 类比对于 999 感冒灵感冒药来说 主作用用于感冒引起的头痛发热鼻塞流涕咽痛等 副作用可见困倦、嗜睡、口渴、虚弱感 理解副作用是相对于主作用来说的一个功能比如函数除了主作用其他的作用就是副作用 对于 React 组件来说主作用就是根据数据state/props渲染 UI除此之外都是副作用比如手动修改 DOM 常见的副作用side effect数据Ajax请求、手动修改 DOM、localStorage、console.log 操作等
总结
对于react组件来说除了渲染UI之外的其他操作都可以称之为副作用
let a 1const Count () {const [count, setCount] useState(0)const handleClick () {setCount(count 1)}console.log(aaa)axios.post(http://xxx)localStorage.setItem()a 2return (divh1计数器{count}/h1button onClick{handleClick}1/button/div)
}3.2 基本使用 使用场景当你想要在函数组件中处理副作用side effect时就要使用 useEffect Hook 了 作用处理函数组件中的一些副作用side effect 注意在实际开发中副作用是不可避免的。因此react 专门提供了 useEffect Hook 来处理函数组件中的副作用
语法
参数回调函数称为 effect就是在该函数中写副作用代码执行时机该 effect 会在组件第一次渲染以及每次组件更新后执行相当于 componentDidMount componentDidUpdate 核心代码 import { useEffect } from reactconst Counter () {const [count, setCount] useState(0)useEffect(() {document.title 当前已点击 ${count} 次})return (divh1计数器{count}/h1button onClick{() setCount(count 1)}1/button/div)
}3.3 依赖
内容 问题如果组件中有另外一个状态另一个状态更新时刚刚的 effect 回调也会执行 默认情况只要状态发生更新 useEffect 的 effect 回调就会执行 性能优化跳过不必要的执行只在 count 变化时才执行相应的 effect 语法 第二个参数可选也可以传一个数组数组中的元素可以成为依赖项deps该示例中表示只有当 count 改变时才会重新执行该 effect 核心代码
import { useEffect } from reactconst Counter () {const [count, setCount] useState(0)const [loading, setLoading] useState(false)useEffect(() {document.title 当前已点击 ${count} 次}, [count])return (divh1计数器{count}/h1button onClick{() setCount(count 1)}1/buttonbutton onClick{() setLoading(!loading)}切换 loading/button/div)
}
3.4 不要对依赖项撒谎
内容
useEffect 回调函数effect中用到的数据比如count就是依赖数据就应该出现在依赖项数组中如果 useEffect 回调函数中用到了某个数据但是没有出现在依赖项数组中就会导致一些 Bug 出现所以不要对 useEffect 的依赖撒谎
const App () {const [count, setCount] useState(0)// 错误演示useEffect(() {document.title 点击了 count 次}, [])return (divh1计数器{count}/h1button onClick{() setCount(count 1)}1/button/div)
}useEffect完全指南https://overreacted.io/zh-hans/a-complete-guide-to-useeffect/ 3.5 依赖项可以是空数组
内容 useEffect 的第二个参数还可以是一个空数组[]表示只在组件第一次渲染后执行 effect 使用场景1 事件绑定 2 发送请求获取数据 等 语法 该 effect 只会在组件第一次渲染后执行因此可以执行像事件绑定等只需要执行一次的操作此时相当于 class 组件的 componentDidMount 钩子函数的作用
useEffect(() {const handleResize () {}window.addEventListener(resize, handleResize)
}, [])注意
跟 useState Hook 一样一个组件中也可以调用 useEffect Hook 多次推荐一个 useEffect 只处理一个功能有多个功能时使用多次 useEffect
3.6 清理工作
内容
effect 的返回值是可选的可省略。也可以返回一个清理函数用来执行事件解绑等清理操作清理函数的执行时机 清理函数会在组件卸载时以及下一次副作用回调函数调用的时候执行用于清除上一次的副作用。如果依赖项为空数组那么会在组件卸载时会执行。相当于组件的componetWillUnmount
核心代码
useEffect(() {const handleResize () {}window.addEventListener(resize, handleResize)// 这个返回的函数会在该组件卸载时来执行// 因此可以去执行一些清理操作比如解绑 window 的事件、清理定时器 等return () window.removeEventListener(resize, handleResize)
}, [])3.7 useEffect的 4 种使用使用方式
// 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])3.8 发送请求
内容 在组件中可以使用 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 () {}
}, [])3.9 axios请求本地json数据
需求:发起axios请求本地某json数据第一步:需要将json文件放在 public 目录下 !!!第二步:引入axios import axios from axios第三步:发起请求
import React, { useEffect, useState } from react
import axios from axios
export default function App() {const [list, setList] useState([])useEffect(() {
//接口地址可省略 public
axios.get(http://localhost:3000/data.json).then((res) {console.log(打印res, res.data)setList(res.data.list)})}, [])return (ul{list.map((item) (li key{item.id}{item.comment}/li))}/ul)
}