用wordpress 建网站,十大搞笑素材网站,滁州网站建设推广,工作室做什么项目好背景#xff1a;习惯了vue的写法#xff0c;并且vue2和vue3都比较熟悉#xff0c;在转react开发中#xff0c;不停的思考react和vue框架的相似之处#xff0c;以及vue中的写法在react里怎么替换。本文将组件更新或组件生命周期角度出发聊聊如何使用hooks触发生命周期… 背景习惯了vue的写法并且vue2和vue3都比较熟悉在转react开发中不停的思考react和vue框架的相似之处以及vue中的写法在react里怎么替换。本文将组件更新或组件生命周期角度出发聊聊如何使用hooks触发生命周期以及如何触发数据更新 为什么要触发组件生命周期 很多没有经验的人不知道为什么要学习框架的生命周期。在开发中我们经常需要弹窗和主页面进行数据传递我现在就遇到很多组件通信的场景主页面更新了弹窗不能关闭弹窗也要更新又或者弹窗更新了立即更新外部页面如tree的状态视图更新等。这里先不考虑组件通信之后在聊。先说组件如何触发更新。 组件什么时候更新这里我们说的概念是主动触发更新。当你明确知道哪个数据变化了一定要更新或者执行了变更操作一定要更新我们就去触发更新。react的hook写法没有提供像vue这种onMountedonUnMountedwatch等监控方法同时它的数据必须通过组件更新才能重新渲染到视图。所以在用react开发的时候更多的是在跟数据打交道有时候莫名奇妙的数据变成undefined或者数据更新了视图不更新。 useEffect useEffect 是 React 中最常用的生命周期管理 Hook。它相当于类组件中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 的组合。 useEffect模拟组件挂载和卸载 最常用的就是useEffect方法这个方法能干什么首先它接受两个参数第一个参数放执行逻辑第二个参数放依赖数组。同时第一个参数的函数返回支持一个return方法。这几项共同演绎了组件更新逻辑。首先如何模拟组件挂载和卸载比如弹窗如果封装为一个组件那么弹窗打开是挂载弹窗关闭是卸载。你如果只想让组件执行一次挂载和卸载逻辑就将依赖项设置一个空数组。在第一个参数写组件挂载逻辑在返回return里执行卸载即清理工作。 示例如下
import React, { useEffect } from react;function Example() {useEffect(() {// 这里执行的代码在组件首次渲染后只执行一次const interval setInterval(() {console.log(Interval running);}, 1000);// 返回一个清理函数用于在组件卸载时清除定时器return () {clearInterval(interval);console.log(Component unmounted);};}, []);return (div{/* 组件内容 */}/div);
}Vue中的onMounted可以在首次渲染后执行一些初始化操作。在React中你可以通过useEffect的依赖项为空来实现这一点 Vue中的onUnmounted可以在组件卸载前执行一些清理操作推荐使用useEffect的返回值来实现更安全的组件卸载逻辑 useEffect模拟数据更新视图 在Vue中组件的更新操作通常是由数据变化触发的Vue会自动处理DOM的更新。而在React中如果你想模拟Vue的组件更新操作你可以使用useState和useEffect钩子来手动控制组件的更新。通过useEffect设置依赖项就可以在依赖项变化时触发其他数据的方法。比如删除数据后触发list刷新保存数据后重新获取数据等。 import React, { useState, useEffect } from react;function Example() {const [count, setCount] useState(0);useEffect(() {// 组件更新时执行console.log(Count changed to ${count});};}, [count]); // 依赖数组当 count 变化时重新执行 useEffectreturn (divpCount is: {count}/pbutton onClick{() setCount(count 1)}Increment/button/div);
}如何触发数据更新 在vue中可以通过ref、reactive等方法直接定义响应式数据数据变化视图自动更新。但是在react数据需要手动管理即哪些是需要视图跟着一起变化的数据需要手动维护。最常用的是useState钩子函数。这个函数通过解构重命名为[变量变量的修改方法]。用法如下 useState
import React, { useState } from react;function MyComponent() {const [count, setCount] useState(0);const handleClick () {setCount(count 1);};return (divpCount: {count}/pbutton onClick{handleClick}Increment/button/div);
}setState后异步获取state不是最新的
如果在一个组件生命周期内先通过方法更改了state但是紧跟着就使用state会出现用的还是旧的state数据。这是因为state还没更新setState是异步的state会在下个组件生命周期更新。所以你会发现你想的数据总是”晚一步“。这点非常不好用如何避免
解决方法 1.更新state时用一个额外的变量存当前最新的state可以用useRef维护一个全局变量直接使用全局变量就行了也可以用一个局部变量然后立即使用这个局部变量 useRef useRef是React提供的一个Hook用于创建一个保持初始值的可变引用。你可以在组件的函数中使用它来存储当前的状态值。 import React, { useState, useRef } from react;function MyComponent() {// 使用useState创建状态const [count, setCount] useState(0);// 使用useRef创建一个引用用于存储当前的count值const currentCount useRef(count);// 当count更新时也更新当前的引用React.useEffect(() {currentCount.current count;}, [count]);return (divp当前计数{currentCount.current}/pbutton onClick{() setCount(count count 1)}增加计数/button/div);
}export default MyComponent;在函数组件中你可以创建一个局部变量并立即使用它来存储当前的状态值。这样你可以立即使用这个局部变量而不用担心状态的延迟更新问题。
import React, { useState } from react;function MyComponent() {const [count, setCount] useState(0);// 创建一个局部变量来存储当前的count值
const update(){
const new count1;setCount(new);
//需要立即使用最新countupdateOther(new);
}
const updateOther (count:number){
//巴拉巴拉
}return (divp当前计数{currentCount}/pbutton onClick{update}增加计数/button/div);
}export default MyComponent;setState更新对象不成功
在React中当使用setState更新对象时如果直接修改状态对象可能会导致原始数据丢失。这是因为React的setState函数在内部使用的是不可变数据结构它会合并新的状态而不是替换整个对象。
以下是一个可能导致原始数据丢失的例子
setState({age: prevState.userInfo.age 1
});在这个例子中你首先获取了prevState.userInfo然后直接在同一个对象上修改了age属性。这样做不会创建一个新的对象因此React不会检测到状态的变化所以界面不会更新。
解决方法
为了避免这种情况你应该始终创建一个新的状态对象如下所示
setState({...prevState.userInfo,age: prevState.userInfo.age 1
});通常用展开运算符复用老数据将需要修改的属性进行变更。