同步修改变量功能封装 useVal for react
同步修改变量功能封装 useVal for react
import { useState, useRef, useCallback } from 'react';
import type { Dispatch, SetStateAction } from 'react';
// 可以当做 useState 用,但数组会多传回一个方法,使用方法可以实时获取最新的值
function useVal<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>, (() => S)] {
let initData = typeof initialState === 'function' ? (initialState as (() => S))() : initialState
// 内部使用 useState
const [data, setData] = useState<S>(() => initData)
// 创建一个 useRef,用来实时给外部提供最新的值
const dataRef = useRef(initData)
// 供外部修改值的方法,方法中会同时给 ref 赋值,供外部随时获取最新值
const setDataExport = useCallback((params: S | ((prevState: S) => S)) => {
// 这里的旧值从ref中取
let oldData = dataRef.current
// 放置新的值的变量
let newData = oldData
// 如果传入的是方法,这里执行得到结果
if (typeof params === 'function') newData = (params as ((prevState: S) => S))(oldData)
// 不是方法,直接赋值
else newData = params
// 先更新ref
dataRef.current = newData
// 再真的去更新 useState 记录的值,这里需要方法返回新值的方式
setData(() => newData)
}, [])
// 供外部获取实时的值的方法
const getRef = useCallback((): S => dataRef.current, [])
return [data, setDataExport, getRef]
}
export { useVal }Last updated