首页 > 解决方案 > 可以卸载并重新安装`` 和 `` 每次更改路线?

问题描述

我需要在路线更改之间显示一个微调器。像这样的东西:

https://codesandbox.io/s/beautiful-williamson-dvxcj

在此处输入图像描述

所以这就是我想出的:

function LayoutLoaderTransition() {
  const [, setForceUpdateBoolean] = useState(false);    // A BOOLEAN STATE TO FORCE RE-RENDERS
  const location = useLocation();                       // WILL RE-RENDER WHEN THE LOCATION CHANGES
  const lastPathname_ref = useRef(null);                // REF TO REMEMBER THE LAST PATHNAME (ROUTE)

  const forceUpdate = useCallback(() => {               // CALLBACK TO FORCE UPDATE THIS COMPONENT
    setForceUpdateBoolean(prevState => !prevState);     // TOGGLE BOOLEAN STATE
  }, []);

  if (lastPathname_ref.current === null) {              // ON FIRST RENDER, LAST PATH REF IS NULL
    lastPathname_ref.current = location.pathname;       // INITIALIZE IT WITH CURRENT RENDER
  }

  useEffect(() => {                                          // EFFECT TO CHECK IF THERE'S A NEW ROUTE
    if (lastPathname_ref.current !== location.pathname) {    // IF NEW ROUTE IS DIFFERENT THAN LAST
      lastPathname_ref.current = location.pathname;          // UPDATE REF
      setTimeout(() => forceUpdate(), 500);                  // FORCE UPDATE AND LAST PAHTNAME WILL BE === NEW
    }
  }, [forceUpdate, location.pathname]);

  return (
    <React.Fragment>
      <Header />
      {lastPathname_ref.current !== location.pathname ? (    // WHEN NEW PATHNAME !== LAST PATHNAME
        <div>Loading</div>                                   // SHOW LOADING
      ) : (                                                  // OTHERWISE SHOW COMPONENT <Main/>
        <div>
          <Main />
        </div>
      )}
      <Footer />
    </React.Fragment>
  );
}

// <Main/> IS BEING UN-MOUNTED AND RE-MOUNTED BETWEEN ROUTE CHANGES

function Main() {
  return (
    <Switch>
      <Route exact path={HOME} component={Home} />
      <Route exact path={ROUTE1} component={Component1} />
      <Route exact path={ROUTE2} component={Component2} />
    </Switch>
  );
}

它有效,但我发现它有点奇怪,因为我在每次路线更改时卸载并重新安装<Switch>所有<Route>内部。<Main/>通常它们只安装一次,并且只在路线更改之间重新渲染。

这是一个不好的做法吗?通过在每次路由更改时重新安装它们,我是否会冒丢失任何“路由信息”的风险?或者没关系?


注意 1:500ms setTimeout() 此处仅用于演示。在实际代码中,我不需要它。微调器将显示并显示在屏幕上,直到 React 完成渲染下一页。在速度较慢的手机上,微调器的可见时间更长,反之亦然。

看看它在没有超时的情况下看起来如何,并且在 Route2 上呈现了一个沉重的组件。渲染繁重的路线时,用户会看到微调器。

在此处输入图像描述


额外的:

我这样做是因为在移动设备上(较低的 CPU 功率)新路线需要一段时间才能渲染,如果我不显示微调器,则 UX 很糟糕。用户单击 a<Link/>并感觉在新页面完成渲染之前什么都没有发生。所以我需要在路由更改之间显示一个加载器。

笔记:

没有进行 API 调用。当应用程序第一次加载时,数据已经完全存在。如果有 API 调用,我可以处理loading每个组件内部的状态,而不是像我在这里做的那样在更高级别上做。

标签: javascriptreactjsreact-routerreact-router-dom

解决方案


推荐阅读