在同一渲染周期中设置多个搜索参数

set multiple Search Params in the same render cycle

我使用来自 React Router (v6) 的 Tree from mui v5 and I want to add in searchParams node that are selected and expanded. To do this I use the hook useSearchParams

事实是选择事件和展开事件在同一组件呈现中触发。

因此,当第一个通过 setSearchParams(...) 写入参数时,第二个执行相同的操作,但使用与第一个设置的相同的搜索参数和擦除参数。

我制作了一个 CodeSandBox 重现了该行为。

我尝试使用 ref 来允许变异 freshSearchParams但我没有成功。

问题是 TreeView 组件在同一个 Click 上同时调度 onNodeSelect 和 onNodeToggle。您可以做的一件事是自定义 handleTogglehandleSelect 函数,因此它们组合了两个 expandedselected 变量。

对于这种情况,我会采取另一种方法。我会使用一个自定义挂钩来处理 Tree 状态并使用 searchParams 功能包装该状态。您可以从 URL 初始化状态,并在更新状态时更新搜索参数。我将使用 useEffect 来实现 URL 更新,该 useEffect 将状态与 URL 进行比较并进行适当的更新。

这是该自定义挂钩的可能实现。

const useTreeUrlStatus = () => {
  const [searchParams, setSearchParams] = useSearchParams();
  const [state, setState] = useState(() => {
    return {
      selected: searchParams.get("selected") ?? "",
      expanded: searchParams.get("expanded")
        ? searchParams.get("expanded").split(",")
        : []
    };
  });

  useEffect(() => {
    if (
      searchParams.get("selected") !== state.selected ||
      searchParams.get("expanded") !== state.expanded
    ) {
      setSearchParams({
        selected: state.selected,
        expanded: state.expanded.join(",")
      });
    }
  }, [state, searchParams, setSearchParams]);

  const updateState = (key, value) => {
    setState((prevState) => {
      const newState = { ...prevState, [key]: value };
      return newState;
    });
  };

  return [state, updateState];
};

您有一个 working sandbox here 从您发布的沙盒中派生出来的。