关于react useState更新异步问题

目录
  • react useState更新异步
  • 记useState异步更新小坑
    • 问题点

react useState更新异步

当我们使用react中useState这个hook时候,如下

const [page, setPage] = useState(1);
const handlerClick = (e)=>{
    setPage(e.current);
    console.log(page);
}

当我打印page时候,此时page还是1,因为useState的更新是异步的,这和react的机制有关,要解决这个可以这样做

1.使用useState的返回值

 setPage(e.current);
        setPage(prevFoo => {
            console.log('page===========',prevFoo);//page=========== 2
            return prevFoo;
 });

2.自定义hook(第一种方式)

    const useSyncCallback = callback => {
        const [proxyState, setProxyState] = useState({ current: false });
        const Func = useCallback(() => {
          setProxyState({ current: true });
        }, [proxyState]);
        useEffect(() => {
          if (proxyState.current === true) {
            setProxyState({ current: false });
          }
        }, [proxyState]);
        useEffect(() => {
          proxyState.current && callback();
        });
        return Func;
      };
      const funcqq = useSyncCallback(() => {
        console.log('page===========',page);//page=========== 2
      });
//调用
setPage(e.current);
funcqq()

自定义hook(第二种方式)

function useCurrentValue(value) {
    const ref = useRef(value);
    useEffect(() => {
      ref.current = value;
    }, [value]);
    return ref;
}
//调用
 const log = () => {
    setCount(count + 1);
    setTimeout(() => {
      console.log(currentCount.current);
    }, 3000);
  };

3.使用useRef替代useState,第三种方式在自定义hook第二种方式里面已经体现了

4.使用useEffect,在自定义hook第二种方式里面已经体现了

记useState异步更新小坑

问题

在hooks中,修改状态的是通过useState返回的修改函数实现的.它的功能类似于class组件中的this.setState().而且,这两种方式都是异步的.可是this.setState()是有回调函数的,那useState()呢?

问题点

它异步且没有回调函数

const [count,setCount] = useState(1)
useEffect(()=> {
    setCount(2,()=>{
      console.log('测试hooks的回调');
    })
    console.log(count);
  },[])

可以看到提示 “State updates from the useState() and useReducer() Hooks don’t support the second callback argument. To execute a side effect after rendering, declare it in the component body with useEffect().”

是不支持回调函数的形式的。因为setCount是异步的,所以打印count是在改变count之前的。

如果我们想要在打印的时候就拿到最新的值,那么我们可以通过setCount的第二个参数指定依赖项

const [count,setCount] = useState(1)
useEffect(()=> {
    setCount(2)
    console.log(count);
  },[count])

当count发生变化的时候,useEffect就会再次相应,但是这样就会有个问题,当count从1变为2的时候useEffect的回调函数会再次执行,就会分别打印1,2两次。

  useEffect(()=> {
    let currentValue = null
      setCount((preVal)=>{
        currentValue=preVal
        return 2
      })
      if(currentValue!==count){
        console.log(count);
      }
    },[count])

通过添加判断条件,我们可以让想要执行的代码只执行一次

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • ReactHooks批量更新state及获取路由参数示例解析

    目录 一.如何批量更新 控制台输出 二.Hooks如何获取路由参数 执行效果 一.如何批量更新 在[Hooks]中如果单独的进行状态的更新可能会导致页面的多次渲染: import { useState } from 'react'; import { unstable_batchedUpdates } from 'react-dom';//批量更新状态时使用 import React from 'react'; const Example = () => { const [count, setC

  • 解决react中useState状态异步更新的问题

    目录 疑惑 状态异步更新带来的问题 问题示例 问题解决 类组件的解决方案 函数组件的解决方案 其他解决方案 结尾 疑惑 相信刚开始使用react函数组件的小伙伴也遇到过一个坑,就是 useState 更新状态是异步更新的,但是react 并没有提供关于这个问题的解决方案.那我们能否使用自己的方法来解决这个问题呢?答案肯定是可以的. 状态异步更新带来的问题 就拿一个比较常见的场景来说.在react项目中,我们想在关闭对话框后再去处理其他业务.但是 useState 的状态是异步更新的.我们通过se

  • React Hook中useState更新延迟问题及解决

    目录 React Hook中useState更新延迟 React Hook useState连续更新对象问题 React Hook中useState更新延迟 方法一:去掉useEffect的第二个参数 例如以下代码 错误实例 const[zoom, setZoom] = useState(0); useEffect(() = >{     document.getElementById('workspace-content').addEventListener('mousewheel', scr

  • react纯函数组件setState更新页面不刷新的解决

    目录 问题描述: 原因分析: 解决方案: 补:react中,hooks钩子时useState更新不渲染组件的问题 问题描述: const [textList, setTextList] = useState(原数组); setTextList(新数组); 当修改原数组时,如果原数组是个深层数组(不只一层),使用setTextList修改时,不会触发页面刷新 原因分析: 这个涉及到可变对象he不可变对象的知识,在vue和react中,如果更新可变对象时,可能会引起视图更新,这是因为,vue和rea

  • 详解React setState数据更新机制

    为什么使用setState 在React 的开发过程中,难免会与组件的state打交道.使用过React 的都知道,想要修改state中的值,必须使用内部提供的setState 方法.为什么不能直接使用赋值的方式修改state的值呢?我们就分析一下,先看一个demo. class Index extends React.Component { this.state = { count: 0 } onClick = () => { this.setState({ count: 10 }) } re

  • react如何获取state的值并更新使用

    目录 react获取state值并更新使用 在视图层处理 在model层处理 react中state基本使用 有状态组件和无状态组件 state的基本使用 setState修改状态 从JSX中抽离事件处理程序 事件绑定this指向 react获取state值并更新使用 react获取state的值并且修改分为两种情况: 在视图层处理 //在 state 中饭设置初始值 state={       name:'',       age:''  } //通过 控制一个事件触发然后setState 去

  • 关于react useState更新异步问题

    目录 react useState更新异步 记useState异步更新小坑 问题点 react useState更新异步 当我们使用react中useState这个hook时候,如下 const [page, setPage] = useState(1); const handlerClick = (e)=>{     setPage(e.current);     console.log(page); } 当我打印page时候,此时page还是1,因为useState的更新是异步的,这和rea

  • React setState是异步还是同步原理解析

    目录 setState异步更新 那么为什么setState设计为异步呢? 如何获取异步的结果 setState一定是异步的吗? setState异步更新 开发中当组件中的状态发生了变化,页面并不会重新渲染.我们必须要通过setState来告知React数据已经发生了变化,重新渲染页面. 先来看下面的例子: constructor() { super(); this.state = { message: "Hello World", }; } changeText() { this.se

  • React useState超详细讲解用法

    目录 前言 基本用法 initData为非函数的情况 initData为函数的情况 state变化监听 过时状态问题 更新引用数据类型 useState 实现原理 前言 React-hooks 正式发布以后, useState 可以使函数组件像类组件一样拥有 state,也就说明函数组件可以通过 useState 改变 UI 视图.那么 useState 到底应该如何使用,底层又是怎么运作的呢,首先一起看一下 useState . 基本用法 [ state , dispatch ] = useS

  • React深入分析更新的创建源码

    目录 ReactDom.render setState 与 forceUpdate expirationTime的作用 获取currentTime 不同的expirationTime React 的鲜活生命起源于 ReactDOM.render ,这个过程会为它的一生储备好很多必需品,我们顺着这个线索,一探婴儿般 React 应用诞生之初的悦然. 更新创建的操作我们总结为以下两种场景 ReactDOM.render setState forceUpdate ReactDom.render 串联该

  • react函数组件useState异步,数据不能及时获取到的问题

    目录 react useState异步,数据不能获取到 问题 解决方法一 react中useState的使用及注意事项 基本使用 注意事项 react useState异步,数据不能获取到 useState() 属于异步函数,在useState() 第一次存储的时候,值会存储不上 因为react中state的更新是异步的,我们setState后,react不会立刻对值进行改变,而是将其暂时放入pedding队列中.react会合并多个state,然后值render一次,所以不要在循环中使用use

  • React超详细分析useState与useReducer源码

    目录 热身准备 为什么会有hooks hooks执行时机 两套hooks hooks存储 初始化 mount useState mountWorkInProgressHook 更新update updateState updateReducer updateWorkInProgressHook 总结 热身准备 在正式讲useState,我们先热热身,了解下必备知识. 为什么会有hooks 大家都知道hooks是在函数组件的产物.之前class组件为什么没有出现hooks这种东西呢? 答案很简单,

  • React18 useState何时执行更新及微任务理解

    目录 函数式组件中的useState 测试1 测试2 类组件中的setState setState在promise之前定义 setState在promise之后定义 结论 函数式组件中的useState 前言:众所周知useState是异步的,但网络上对于useState何时异步更新并没有一个共识,为了探究,做一个简单的实验,实验目的是探究useState与微任务.宏任务的先后关系 测试1 实验步骤:点击按钮触发事件,在事件中我们做三件事:修改state/定义一个宏任务setTimeout /定

  • 教你react中如何理解usestate、useEffect副作用、useRef标识和useContext

    目录 1.usestate 1.1一般使用 1.2 useState回调函数作为参数 2.useEffect副作用 2.1 useEffect副作用及其使用 2.2 useEffect清理副作用 2.3 useEffect发送网络请求 3.自定义hook函数 4.useRef的使用 5.useContext的使用 1.usestate 1.1一般使用 注意:useState 的初始值(参数)只会在组件第一次渲染时生效.也就是说,以后的每次渲染,useState 获取到都是最新的状态值,React

随机推荐