gpt4 book ai didi

javascript - 带有路由的 React 中的单页应用程序 - 相同的结构,不同的内容

转载 作者:行者123 更新时间:2023-12-05 05:33:26 24 4
gpt4 key购买 nike

问题

我正在尝试在 React 中使用路由(最好使用 React 钩子(Hook))制作 SPA,但我发现的所有示例和描述都是关于根据 URL 显示不同的组件。我想要的是 Youtube 或 Google 文档之类的东西,其中页面结构/组件(大部分)相同,只有内容发生变化。

上下文

(编辑:添加更多上下文。)

这将是一个文档编辑器/演示器。

页面结构:登录后,顶部总是有一个工具栏(蓝色),用于菜单、通知等。屏幕的其余部分将大致如下两个示例所示:

示例 1: enter image description here示例 2: enter image description here

搜索 Pane (橙色)可以通过工具栏上的按钮或用户 session 变量打开/关闭。该文档将根据用户 session 变量、URL 中提供的文档 ID 或在搜索 Pane 中选择的文档显示在文档部分(灰色)。

计划的 URL

(在编辑中添加。)

  • 着陆页:/login,登录页。

  • 着陆页:/,此处将显示工具栏和预配置的、基于用户 session 的默认文档。

  • 文档页面:/doc?id=oys2OPkfOwQ,与着陆页相同,但文档部分将包含 ID 作为查询参数提供的文档。

  • 任何其他东西:/something,工具栏和它下面的东西。

想法

(在编辑中添加。)

布局由 CSS 网格定义,页面结构根据变量变化。因此,这将成为来自默认值和用户 session 配置变量的 App 组件的 Prop ,以后可能会更改。

这是我想象的 App 组件的功能(类似伪代码的东西):

<Router>
<Route path='/login'>
<Login/>
// Components: Toolbar and something under it
</Route>
<Route path='/'>
<DocApp/>
// Components: Toolbar, Document or Toolbar, Search and Document
// Default document loaded for default, not logged in user
// Default document loaded from stored user session
</Route>
<Route path='/doc'>
<DocApp/>
// Components: Toolbar, Document or Toolbar, Search and Document
// Same as for '/' except document with ID set as query param is displayed
// This could be called/triggered from search and document component as well
</Route>
<Route path='/somethingelse'>
<SomethingElse/>
</Route>
</Router>

问题

(编辑:改写,最初的问题是如何实现基于 URL 查询参数加载不同文档的解决方案。)

如果有更简单的方法来绘制着陆布局'/' 和特定文档演示者/doc?id=oys2OPkfOwQ 布局,我最感兴趣的是什么?在这两种情况下,都会显示相同的组件,只是提供的参数(提供的文档)不同。

解决方案

(在编辑中添加。)

通过阅读答案和反馈并重新思考我的问题,我意识到我有一个 multiple URLs same content problem .

最佳答案

使用 React Router 渲染基于 UrlParams 的组件。

首先,编辑您的路由以在路由 /doc 下呈现 DocumentLoader 组件

// file: app.js

import React from "react";
import { BrowserRouter, Route } from "react-router-dom";
import DocumentLoader from "./DocumentLoader";

const App = (props) => {

return <BrowserRouter>
<Routes>
<Route path="/doc" element={<DocumentLoader />}>
</Routes>
</BrowserRouter>
}

为加载文档创建自定义 Hook

您需要两个自定义 Hook ,一个用于通过更改 docId 查询参数加载新文档,另一个 Hook 用于监听 docId 更改以从后端重新加载新文档。

注意:编辑 loadDocumentData 以从后端加载

// file: hooks.js

import { useState, useEffect, useCallback } from 'react';
import { useSearchParams } from 'react-router-dom';

/**
* TODO:// Refactor this function to call your backend to get
* Document data by docId
*/
const loadDocumentData = (docId) =>
new Promise((resolve, reject) => {
// this setTimeout for demonstration porpuse only
setTimeout(() => {
resolve({ id: docId, name: `Document name for ${docId}` });
}, 3000);
});

export const useDocument = () => {
const [loading, setLoading] = useState(true);
const { docId, loadDocument } = useDocumentParam();
const [document, setDocument] = useState(null);

useEffect(() => {
setLoading(true);

// Load your document data based on docID
loadDocumentData(docId)
.then((doc) => {
setDocument(doc);
setLoading(false);
})
.catch((e) => {
console.error('Failed to load doc', docId);
});
}, [docId, setLoading]);

return { document, loading, loadDocument };
};

export const useDocumentParam = () => {
const [searchParams, setSearchParams] = useSearchParams();
const docId = searchParams.get('d');

const loadDocument = useCallback(
(newDocId) => {
setSearchParams({ d: newDocId });
},
[setSearchParams]
);

return { docId, loadDocument };
};


创建 DocumentLoader 组件

要监听查询参数的变化,从服务器端加载文档,显示加载指示器并呈现“DocPresenter”组件。

// file: DocumentLoader.js

import * as React from 'react';
import DocPresenter from './DocPresenter';
import { useDocument } from './hooks';

const DocumentLoader = (props) => {
const { loading, document, loadDocument } = useDocument();

if (loading) {
return <div>Display loading indicator while loading the document</div>;
}

return (
<div className="document-container">
<div className="toolbar">NavBar</div>
<div className="searchbox">search component</div>
<div className="editor">
<DocPresenter document={document} setParentstate={loadDocument} />
</div>
</div>
);
};

export default DocumentLoader;


结帐Live Example在 StackBlitz 上。

帮助链接:

关于javascript - 带有路由的 React 中的单页应用程序 - 相同的结构,不同的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73848458/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com