专门做鞋子的网站吗,晨阳seo,个性化定制软件,桂建云平台注册副作用#xff1a;和外部有交互 引用外部变量调用外部函数修改dom、全局变量ajax计时器#xff08;依赖window.setTimeout#xff09;存储相关 纯函数#xff1a;相同的输入一定会得到相同的输出 Effect Hook可以让你在函数组件中执行副作用操作 类组件中处理副作用
在com… 副作用和外部有交互 引用外部变量调用外部函数修改dom、全局变量ajax计时器依赖window.setTimeout存储相关 纯函数相同的输入一定会得到相同的输出 Effect Hook可以让你在函数组件中执行副作用操作 类组件中处理副作用
在componentDidMount/componentDidUpdate声明周期中真实dom构建以前
useEffect执行时机
初次渲染之后 didMount真实dom构建以后渲染更新时 didUpdate是异步的在回调函数中拿到更新的state
存在清理函数
首次执行 render → useEffect再次执行 render → 清理函数 → useEffect清理函数组件更新、组件销毁时执行
组件更新
useEffect(() {console.log(useEffect)return () {console.log(clear Effect)}
})import { useState, useEffect } from react
export default function App(props) {const [count, setCount] useState(() {console.log(1); // 惰性初始化只会打印一次return 1});useEffect(() {// 持续递增console.log(useEffect)let timer setInterval(() { // 2. 每一次副作用都会重新初始化一个timersetCount(count 1)}, 1000)return () {clearInterval(timer) // 1.闭包 第二次运行时先清理上一次的timerconsole.log(clear Effect)}})return (h1{count}/h1/)
}组件销毁
import { useState, useEffect } from react
function Test() {const [count, setCount] useState(1);useEffect(() {console.log(useEffect)return () {console.log(clear Effect) // 组件更新、销毁时执行}})return (h1{count}/h1button onClick{() setCount(count 1)}add/button/)
}
export default function App() {const [show, setShow] useState(true)return ({show Test /}button onClick{() setShow(!show)}changeShow/button/)
}只在didMount时执行
依赖项
指定当前effect函数所需要的依赖项若依赖项是[]在初次渲染和卸载的时候执行若依赖项不变effect不执行存在依赖项 依赖项更新时effect执行
import { useState, useEffect } from react
function Test() {const [count, setCount] useState(1);useEffect(() {console.log(useEffect)let timer setInterval(() { // didMount时执行一次// setCount(count 1) // 若在依赖项中未填入count则此时count拿到的一直是0// 但填入count依赖不能解决“只在didMount时执行”的问题// 改成回调的方式能获取最新的countsetCount(count count 1)}, 1000)return () {clearInterval(timer) // 组件销毁时执行didMount时不执行console.log(clear Effect)}}, []) // 增加了依赖项return (h1{count}/h1button onClick{() setCount(count 1)}add/button/)
}
export default function App() {const [show, setShow] useState(true)return ({show Test /}button onClick{() setShow(!show)}changeShow/button/)
}竞态问题
接口返回的时长不同后返回的覆盖了之前的数据导致没有渲染正确的结果
现象结果3覆盖了4
import { useState, useEffect } from react
const API {async queryEmployeesByid(id) {return new Promise((resolve) {setTimeout(() {resolve({id,currentDepartment: currentDepartment:${id}})}, 300 * (10 - id))// id越大返回越快模拟后发的请求比先发的请求快})}
}
const Department props {let { id } props;let [employees, setEmployees] useState({})useEffect(() {let didCancel false; // 解决竞态问题(async function fetchData() {let employee await API.queryEmployeesByid(id)// 解决竞态问题最后一次点的时候先true再false拿到对应id的请求结果if (!didCancel) {setEmployees(employee)}})()return () { // 解决竞态问题didCancel true}}, [id])return ({employees.currentDepartment}/)
}
const App params {let [id, setId] useState(1)return (pid:{id}/pDepartment id{id} /br /button onClick{() setId(id 1)}id/button/)
}
export default App