是否可以在每次更改路径时卸载并重新安装`<Switch>`和`<Route>`吗?

时间:2020-05-15 10:15:47

标签: javascript reactjs react-router react-router-dom

我需要展示路线更改之间的旋转器。像这样:

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

enter image description here

这就是我想出的:

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上呈现了一个沉重的组件。在绘制繁重的路线时,用户可以看到微调器。

enter image description here


额外:

之所以这样做,是因为在移动设备(CPU功率较低)上,新路径需要花费一些时间来渲染,而且如果我不显示微调器,则UX会很糟糕。用户单击<Link/>,直到新页面完成渲染,感觉什么都没发生。因此,我需要在路线更改之间显示一个加载程序。

注意:

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

0 个答案:

没有答案