簡體   English   中英

具有動態路徑和動態組件的 React Router

[英]React Router with dynamic path and dynamic component

我正在構建具有分層結構的應用程序,並且能夠通過管理面板設置用戶想要的任何 slug url。 例如,如果首頁有 url news而里面的頁面有 url new_telescope ,那么整個 url 就是/news/new_telescope/ 我編寫了 url 控制器來處理這個問題,所以 url 中有多少級別並不重要 - 我從服務器獲取所需頁面的數據。 所以我的React Router不會有預定義的 url——我需要獲取當前的 url,將其發送到服務器,獲取數據,獲取組件並渲染它。 現在看起來像這樣:

function getRoute() {
    url.splice(0, 1);
    adminRequest(
        'get',
        constants.SERVER_ADDRESS + `/system/url/?url=` + JSON.stringify(url) + '&version=1',
    ).then(response => {
        const CurrentComponent = lazy(() => import('./' + response.data.template));
        return <Route path={window.location.pathname} element={<CurrentComponent page={response.data}/> } />
    });
}

return (
    <>
        <Suspense fallback={<div className='preloader'><CircularProgress size='75px' /></div>}>
            <Routes>
                // trying to get the current url with proper component
                { getRoute() }
                <Route path="/admin/" element={<Admin />} />
                <Route path="/admin/login/" element={<Login />} />
                ...
            </Routes>
        </Suspense>
    </>
);

所以問題出在getRoute函數上。 如您所見,我提出了一個請求,從數據庫中獲取組件名稱並使用lazy導入它。 在該函數中,我創建了一個新Route以將其放入Routes 但我收到錯誤No routes matched location 當然,組件不會渲染。 我認為Suspense會等待第一條路線出現,但它不會那樣工作。 如何讓Router等待動態路由?

問題

  1. getRoute函數不返回任何內容。 當然,從adminRequest開始的 Promise 鏈會返回一些 JSX,但其他函數不會返回解析后的值。
  2. React 渲染函數是 100% 同步函數。 您不能調用異步函數並期望 React 等待任何異步代碼解析以呈現任何內容。

解決方案

使用useEffect掛鈎發出獲取路由的副作用。 無條件渲染Route但有條件地渲染element值。

const [data, setData] = useState();
const [CurrentComponent, setCurrentComponent] = useState();

useEffect(() => {
  const getRoute = async () => {
    url.splice(0, 1);
    const response = await adminRequest(
      "get",
      constants.SERVER_ADDRESS +
        `/system/url/?url=` +
        JSON.stringify(url) +
        "&version=1"
    );
    
    const CurrentComponent = lazy(() =>
      import("./" + response.data.template)
    );
    
    setData(response.data);
    setCurrentComponent(CurrentComponent);
  };

  getRoute();
}, [url]);

...

<Suspense fallback={<div className="preloader">Loading...</div>}>
  <Routes>
    <Route
      path={/* whatever the path is */}
      element={CurrentComponent ? <CurrentComponent page={data} /> : null}
    />
    <Route path="/admin/" element={<Admin />} />
    <Route path="/admin/login/" element={<Login />} />
  </Routes>
</Suspense>

演示

編輯 react-router-with-dynamic-path-and-dynamic-component

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM