自定义hooks之useLastState、useSafeState

自定义hooks之useLastState、useSafeState

useLastState

在某些情况下,可能需要知道状态的历史值,例如,希望在状态变化时执行某些操作,但又需要访问上一个状态的值,以便进行比较或其他操作。自定义 React Hook 可以帮助我们封装和重用组件逻辑。这里介绍的useLastState Hook 可以用于跟踪组件状态的历史变化,可以获取上一个状态的值。

以下是一个实现 useLastState Hook 的示例:

复制代码
import { useState, useEffect } from 'react';

function useLastState(initialState) {
  const [state, setState] = useState(initialState);
  const [lastState, setLastState] = useState(initialState);

  // 使用 useEffect 来监听 state 的变化,并在 state 变化时更新 lastState
  useEffect(() => {
    setLastState(state);
  }, [state]);

  // 返回一个包含当前 state 和上一个 state 的数组
  return [state, lastState, setState];
}

export default useLastState;

上面的 useLastState Hook 接受一个初始状态值作为参数,并返回一个包含当前状态、上一个状态以及一个更新状态的函数的数组。

使用这个 Hook 的示例:

复制代码
import React from 'react';
import useLastState from './useLastState';

function MyComponent() {
  const [count, lastCount, setCount] = useLastState(0);

  const handleIncrement = () => {
    setCount(count + 1);
  };

  return (
    <div>
      <p>Current Count: {count}</p>
      <p>Last Count: {lastCount}</p>
      <button onClick={handleIncrement}>Increment</button>
    </div>
  );
}

export default MyComponent;

在上述示例中,MyComponent 使用 useLastState Hook 来跟踪 count 的状态,并在界面上显示当前计数和上一个计数的值。当点击 "Increment" 按钮时,count 会增加,同时 lastCount 会更新为前一个状态的值。

使用场景

  1. 图表组件 :当需要在图表组件中跟踪数据的历史变化,以便在数据变化时执行比较或动画效果时,可以使用 useLastState。例如,在绘制图表时,可以比较当前数据和上一次数据,以确定何时触发图表的动画效果。

  2. 计数器组件:在计数器组件中,可能希望显示当前计数值以及上一次计数值,以便用户可以看到计数的变化情况。

  3. 表格排序 :当用户点击表格列标题进行排序时,可以使用 useLastState 来跟踪上一次的排序状态,以确定排序的方向(升序或降序),并在表格中显示排序箭头。

useSafeState

useSafeState 是一个自定义 React Hook,用于确保在组件卸载后不再更新组件状态。这是为了解决异步操作(如数据请求或定时器)可能在组件卸载后仍然触发状态更新的常见问题,有助于处理异步操作和组件生命周期的常见问题的方式,确保组件卸载后不再更新状态,提高了代码的稳定性。

以下是一个实现 useSafeState Hook 的示例:

复制代码
import { useState, useEffect, useCallback } from 'react';

function useSafeState(initialState) {
  const [state, setState] = useState(initialState);
  const isMounted = useRef(true);

  useEffect(() => {
    isMounted.current = true;
    return () => {
      isMounted.current = false;
    };
  }, []);

  const safeSetState = useCallback(
    (newState) => {
      if (isMounted.current) {
        setState(newState);
      }
    },
    [setState]
  );

  return [state, safeSetState];
}

export default useSafeState;

使用这个 Hook 的示例:

复制代码
import React, { useEffect } from 'react';
import useSafeState from './useSafeState';

function MyComponent() {
  const [count, setCount] = useSafeState(0);

  useEffect(() => {
    const timer = setInterval(() => {
      setCount((prevCount) => prevCount + 1);
    }, 1000);

    return () => {
      clearInterval(timer); // 确保在组件卸载时清除定时器
    };
  }, [setCount]);

  return (
    <div>
      <p>Count: {count}</p>
    </div>
  );
}

export default MyComponent;

在上述示例中,useSafeState Hook 用于跟踪计数的状态,同时在组件卸载时清除定时器。这确保了即使在组件卸载后,定时器仍然触发状态更新的情况下,不会引发 React 的警告或错误。

使用场景

  1. 数据请求 :在进行数据请求时,如果请求返回数据需要更新组件的状态,但在请求期间用户可能离开当前页面或组件已卸载,为了避免在组件卸载后更新状态而导致错误,可以使用 useSafeState

  2. 定时器 :在使用定时器执行周期性任务时,如果组件在定时器触发时已经卸载,为了防止更新已卸载组件的状态,可以使用 useSafeState 来确保定时器回调函数不会触发状态更新。

  3. 事件监听器 :在添加 DOM 事件监听器时,如果组件卸载时没有正确移除事件监听器,可能会导致内存泄漏或不稳定的行为。useSafeState 可以用于确保在组件卸载时不再触发事件监听器的回调函数。

本文使用 文章同步助手 同步

相关推荐
Wiktok20 分钟前
pureadmin的动态路由和静态路由
前端·vue3·pureadmin
devii6621 分钟前
html.
前端
掘金安东尼25 分钟前
为什么浏览器要限制 JavaScript 定时器?
前端·javascript·github
学前端搞口饭吃29 分钟前
react context如何使用
前端·javascript·react.js
GDAL34 分钟前
为什么Cesium不使用vue或者react,而是 保留 Knockout
前端·vue.js·react.js
IT_陈寒35 分钟前
《Java 21新特性实战:5个必学的性能优化技巧让你的应用快30%》
前端·人工智能·后端
小谭鸡米花1 小时前
uni小程序中使用Echarts图表
前端·小程序·echarts
芜青1 小时前
【Vue2手录11】Vue脚手架(@vue_cli)详解(环境搭建+项目开发示例)
前端·javascript·vue.js
a别念m1 小时前
前端架构-CSR、SSR 和 SSG
前端·架构·前端框架
BillKu6 小时前
Vue3 + Element-Plus 抽屉关闭按钮居中
前端·javascript·vue.js