V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
Envov
V2EX  ›  问与答

react 使用 hooks,遇到问题,没有想到好的解决办法

  •  
  •   Envov · 2022-11-18 18:02:26 +08:00 · 810 次点击
    这是一个创建于 496 天前的主题,其中的信息可能已经有所发展或是发生改变。

    想要封装一个 useUrlState

    useUrlState 是我封装的 hooks ,返回 state 和 stateSetter
    另外如果在多个组件中使用同一个 key( useUrlState 的第一个参数),那么组件之间就可以共享 setter 和 state
    以下是 API 调用的形式:

      const [searchWord, searchWordSet] = useUrlState("searchWord", "");
      const [filterStatus, filterStatusSet] = useUrlState("filterStatus", "");
    
      <input value={searchWord} onChange={e=>searchWordSet(e.target.value)}/>
    

    实现是这样的

    在 react-router v6 基础山,封装了一下 useSearchParams

    import { useCallback, useEffect } from "react";
    import { useSearchParams, NavigateOptions } from "react-router-dom";
    export const navigateOptions: NavigateOptions = {
      replace: true,
    };
    
    const useUrlState = (key: string, state: string) => {
      const [searchParams, setSearchParams] = useSearchParams();
    
      useEffect(() => {
        const hasStateInUrl = searchParams.has(key);
        const urlState = searchParams.get(key) || "";
        if (!hasStateInUrl && urlState !== state) {
          searchParams.set(key, state);
          setSearchParams(searchParams, navigateOptions);
        }
      }, [searchParams, state, key]);
    
      const setter = useCallback(
        (newState: string) => {
          searchParams.set(key, newState);
          setSearchParams(searchParams, navigateOptions);
        },
        [key, searchParams]
      );
    
      return [searchParams.get(key) || state, setter] as const;
    };
    export default useUrlState;
    
    

    出现一个问题

    正常情况下使用表现良好,但是如果出现连续的 setter ,例如

    const [pageSize,pageSizeSet]=useUrlstate("pageSize","10");
    const [pageIndex,pageIndexSet]=useUrlstate("pageIndex","1");
    
    //下面是连续调用 setter
    onPagingChange({ pageIndex, pageSize }) {
                pageSizeSet(pageSize);
                pageIndexSet(pageIndex)
    }
    

    连续的 setter 的第一个不会生效,例如👆的代码 pageSizeSet 就不会生效。
    原因是因为两个 setter 执行起点是一样的,最后只有后面那个覆盖前面的
    我尝试 setSearchParams 接受变更函数来更改 url ,结果依旧会产生覆盖的 bug 。

    求解决思路

    XCFOX
        1
    XCFOX  
       2022-11-18 20:25:08 +08:00   ❤️ 1
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   986 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 21:57 · PVG 05:57 · LAX 14:57 · JFK 17:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.