【发布时间】:2021-06-05 22:18:34
【问题描述】:
我有一个使用 React 和 Express Node 构建的应用程序,其中有 3 个独立的组件。第一个组件是图库,用户可以在其中选择一张图片来创建带有背景图片的帖子。单击按钮时,用户将进入表单。用户将使用一些文本编辑输入并保存具有 axios.post 请求的表单,以通过快速路由将数据发送到 mongo db。保存用户点击后,查看帖子会将他们带到另一个组件,其中 axios.get 请求向用户显示图像和输入数据。
我的路由具有唯一的 http 路径来显示处于活动状态的组件。我的问题是如何映射路由以动态加载来自 mongodb 集合的图像名称,而不是手动写入路径图像名称,即:path={"/getinputwaterfall/:id"}、path={"/getinputcross/:id"}、path={"/getinputfreedom/:id"}。我想改为:path={"/getinput{urlName}/:id"}。
在 mongoDB 集合中,我有一个 URL 和名称字符串数组。 URL 字符串是来自 firebase 的 http 路径,名称字符串是图像名称。
这可能吗? 下面是代码和我的尝试。
import React, {useState, useEffect} from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import axios from "axios";
import "bootstrap/dist/css/bootstrap.min.css";
import "./index.css";
//gallery imports
import Cross from "./Components/Gallery/posts/Cross";
import Waterfall from "./Components/Gallery/posts/Waterfall";
import Freedom from "./Components/Gallery/posts/Freedom";
import CrossPost from "./Components/Gallery/get/CrossPost";
import WaterfallPost from "./Components/Gallery/get/WaterfallPost";
import FreedomPost from "./Components/Gallery/get/FreedomPost";
function App() {
const [name, setName] = useState([]);
const loadImage = async () => {
try {
let res = await axios.get("http://localhost:5000/geturls");
console.log(res.data)
setName(res.data.map(n=>n.name)); //array of names
} catch (error) {
console.log(error);
}
};
useEffect(() => {
loadImage();
}
,[]);
return (
<div className="App">
<Router>
<Switch>
{/* routes for gallery */}
<Route path={"/waterfall"} component={Waterfall} />
<Route path={"/cross"} component={Cross} />
<Route path={"/freedom"} component={Freedom} />
<Route path={"/getinputwaterfall/:id"} component={WaterfallPost} />
<Route path={"/getinputcross/:id"} component={CrossPost} />
<Route path={"/getinputfreedom/:id"} component={FreedomPost} />
{/* what I tryed to map */}
{name.filter(name => name === `${name}` ).map((urlName) => (
<Route exact path={`/getinputt/${urlName}`} component={CrossPost} />
))}
</Switch>
</Router>
</div>
);
}
export default App;
更新:对于那些希望看到完整解决方案的人,我将答案的第一个选项应用于我的代码:注意:我必须删除 /getinput/${name}/:id 中的“/”才能使我的代码正常工作!谢谢德鲁!
const imagePostRoutes = [
{ name: "cross", component: CrossPost },
{ name: "freedom", component: FreedomPost },
{ name: "waterfall", component: WaterfallPost },
];
return (
<div className="App">
<Router>
<Switch>
{imagePostRoutes.map(({ component, name }) => (
<Route
key={name} path={`/getinput${name}/:id`} component={component}
/>
))}
</Switch>
</Router>
</div>
);
}
【问题讨论】:
-
你好。是什么驱动“getinputwaterfall”/“getinputcross”?...路径段?或者这正是您在区分路线时所尝试的?您是否提前知道动态路径可能是什么? (似乎你可能会因为你有
WaterfallPost、CrossPost、.... 组件)你可以创建一个“路由配置”来保存具有路径段名称和应该为该路由呈现的组件。 -
@DrewReese 你说得对,我只是想让路线独一无二,它们都来自同一个控制器,这是让一个组件超越另一个组件的唯一方法。你能给我一个路由配置的例子吗,或者我可以用谷歌搜索一下吗?
-
当然。
[{ name: "waterfallPost", component: WaterfallPost }, { name: "crossPost", component: CrossPost }, ....],然后将它们全部映射到路线。或者,您可以定义单个动态路由,例如<Route path="/:imagePostType/:id" component={ImagePost} />并定义要在ImagePost中使用的 Map,它使用imagePostType作为返回要呈现的发布组件的键。 -
谢谢你,但仍然不确定如何写出来,我还是个新手,我尝试实现你向我展示的动态选项,但不确定:请参阅上面的更新跨度>
标签: reactjs loops express for-loop react-router