hooks
hooks copied to clipboard
feat: add useProState hook
🤔 This is a ...
- [x] New feature
- [ ] Bug fix
- [x] Site / documentation update
- [x] Demo update
- [x] TypeScript definition update
- [ ] Bundle size optimization
- [ ] Performance optimization
- [ ] Enhancement feature
- [ ] Internationalization
- [ ] Refactoring
- [ ] Code style optimization
- [ ] Test Case
- [ ] Branch merge
- [ ] Other (about what?)
🔗 Related issue link
close: https://github.com/alibaba/hooks/issues/2432
💡 Background and solution
📝 Changelog
Language | Changelog |
---|---|
🇺🇸 English | add useProState |
🇨🇳 Chinese |
☑️ Self Check before Merge
⚠️ Please check all items below before review. ⚠️
- [x] Doc is updated/provided or not needed
- [x] Demo is updated/provided or not needed
- [x] TypeScript definition is updated/provided or not needed
- [x] Changelog is provided or not needed
这个往 v4 分支合
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
5 out of 6 committers have signed the CLA.
:white_check_mark: guoyunhe
:white_check_mark: coding-ice
:white_check_mark: joe-leong
:white_check_mark: guaijie
:white_check_mark: LonelyFellas
:x: crazylxr
You have signed the CLA already but the status is still pending? Let us recheck it.
都可以了,分支从master
切的,没太注意,抱歉~
目前的getState还是不能实时获取到期待的setState之后的值,见这个issues,https://github.com/alibaba/hooks/issues/2631
我这里改写setState,在setState之前获取要赋值的新值,塞给ref,这样ref就能同步获取到最新的值了, 大佬们看看这样是否可行,有什么隐患
import { useState, type Dispatch, type SetStateAction, useCallback, useRef } from 'react';
import { isFunction } from 'ahooks/es/utils';
export type SetMergeState<S extends Record<string, never>> = <K extends keyof S>(
state: Pick<S, K> | null | ((prevState: Readonly<S>) => Pick<S, K> | S | null),
) => void;
export type DispatchType<S> = Dispatch<SetStateAction<S>>;
function useProState<S extends Record<string, never>>(
initialState?: S | (() => S),
): [
S,
{
setState: DispatchType<S>;
getState: () => S;
resetState: () => void;
setMergeState: SetMergeState<S>;
},
];
function useProState<S>(initialState?: S | (() => S)): [
S,
{
setState: DispatchType<S>;
getState: () => S;
resetState: () => void;
setMergeState: (s: Record<string, never>) => void;
},
];
function useProState<S>(initialState: S) {
const [state, setStatePrivate] = useState<S>(initialState);
const currentStateRef = useRef(state);
const setState = useCallback((patch: unknown) => {
const newState = isFunction(patch) ? patch(state) : patch;
setStatePrivate(newState);
currentStateRef.current = newState;
}, [state]);
const getState = useCallback(() => currentStateRef.current, []);
const resetState = useCallback(() => {
setState(initialState);
}, []);
const setMergeState = useCallback((patch: unknown) => {
const newState = isFunction(patch) ? patch(state) : patch;
const result = newState ? { ...state, ...newState } : state;
setStatePrivate(result);
currentStateRef.current = result;
}, [state]);
return [state, { setState, getState, resetState, setMergeState }];
}
export default useProState;
目前的getState还是不能实时获取到期待的setState之后的值,见这个issues,#2631 我这里改写setState,在setState之前获取要赋值的新值,塞给ref,这样ref就能同步获取到最新的值了, 大佬们看看这样是否可行,有什么隐患
import { useState, type Dispatch, type SetStateAction, useCallback, useRef } from 'react'; import { isFunction } from 'ahooks/es/utils'; export type SetMergeState<S extends Record<string, never>> = <K extends keyof S>( state: Pick<S, K> | null | ((prevState: Readonly<S>) => Pick<S, K> | S | null), ) => void; export type DispatchType<S> = Dispatch<SetStateAction<S>>; function useProState<S extends Record<string, never>>( initialState?: S | (() => S), ): [ S, { setState: DispatchType<S>; getState: () => S; resetState: () => void; setMergeState: SetMergeState<S>; }, ]; function useProState<S>(initialState?: S | (() => S)): [ S, { setState: DispatchType<S>; getState: () => S; resetState: () => void; setMergeState: (s: Record<string, never>) => void; }, ]; function useProState<S>(initialState: S) { const [state, setStatePrivate] = useState<S>(initialState); const currentStateRef = useRef(state); const setState = useCallback((patch: unknown) => { const newState = isFunction(patch) ? patch(state) : patch; setStatePrivate(newState); currentStateRef.current = newState; }, [state]); const getState = useCallback(() => currentStateRef.current, []); const resetState = useCallback(() => { setState(initialState); }, []); const setMergeState = useCallback((patch: unknown) => { const newState = isFunction(patch) ? patch(state) : patch; const result = newState ? { ...state, ...newState } : state; setStatePrivate(result); currentStateRef.current = result; }, [state]); return [state, { setState, getState, resetState, setMergeState }]; } export default useProState;
可以考虑一下, @coding-ice 你看看呢,获取最新值的问题