【问题标题】:How to map a filter of a string value in an array of strings如何在字符串数组中映射字符串值的过滤器
【发布时间】: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”?...路径段?或者这正是您在区分路线时所尝试的?您是否提前知道动态路径可能是什么? (似乎你可能会因为你有 WaterfallPostCrossPost、.... 组件)你可以创建一个“路由配置”来保存具有路径段名称和应该为该路由呈现的组件。
  • @DrewReese 你说得对,我只是想让路线独一无二,它们都来自同一个控制器,这是让一个组件超越另一个组件的唯一方法。你能给我一个路由配置的例子吗,或者我可以用谷歌搜索一下吗?
  • 当然。 [{ name: "waterfallPost", component: WaterfallPost }, { name: "crossPost", component: CrossPost }, ....],然后将它们全部映射到路线。或者,您可以定义单个动态路由,例如 &lt;Route path="/:imagePostType/:id" component={ImagePost} /&gt; 并定义要在 ImagePost 中使用的 Map,它使用 imagePostType 作为返回要呈现的发布组件的键。
  • 谢谢你,但仍然不确定如何写出来,我还是个新手,我尝试实现你向我展示的动态选项,但不确定:请参阅上面的更新跨度>

标签: reactjs loops express for-loop react-router


【解决方案1】:

我首先建议创建一个可以映射的“路由”配置数组。

const imagePostRoutes = [
  { name: "cross", component: CrossPost },
  { name: "freedom", component: FreedomPost },
  { name: "waterfall", component: WaterfallPost },
];

...

{imagePostRoutes.map(({ component, name }) => (
  <Route key={name} path={`/getInput/${name}/:id`} component={component} />
))}

第二个建议是使用单个通用动态路由,其中​​匹配参数可以指定帖子类型和通用帖子组件来呈现特定的图像帖子组件。这是一个非常精简的最小版本。

  1. 定义路线。

    <Route path="/getInput/:imagePostType/:id" component={ImagePost} />
    
  2. 创建一个匹配参数映射到要渲染的组件。

    const postComponents = {
      cross: CrossPost,
      freedom: FreedomPost,
      waterfall: WaterfallPost,
    };
    
  3. 创建一个组件来读取匹配参数并从地图加载正确的帖子组件。

    const ImagePost = () => {
      const { id, imagePostType } = useParams();
    
      const Component = postComponents[imagePostType];
    
      if (!Component) {
        return "Unsupported Image Post Type";
      }
    
      return <Component id={id} />;
    }
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-28
    • 2021-11-15
    • 1970-01-01
    • 2012-08-21
    • 2017-09-17
    • 2021-06-05
    • 2020-12-12
    • 1970-01-01
    相关资源
    最近更新 更多