【问题标题】:Filter results from nested Arrays (small React application)过滤嵌套数组的结果(小型 React 应用程序)
【发布时间】:2020-04-09 23:29:48
【问题描述】:

我正在尝试解决在 FrontEndMentor 上发现的挑战。在本练习中,我必须映射 Data.Js 文件并显示内容。之后,我必须根据单击相应按钮的各种类别过滤这些结果。这是我的 App.js 组件:

function App() {

  const [jobs, setJobs] = useState(Data)

  const filterThis = (e, type)=>{

   let categorySelected =  e.target.value; 
   console.log(categorySelected);

   if(type==="role"){
     setJobs(Data.filter(job=> job.role===categorySelected))
   } else if (type==="level"){
    setJobs(Data.filter(job=> job.level===categorySelected))
   }else if(type==="languages"){
      ???????
   }
  }

  return (
    <div className="App">
      <header></header>
      <div className="container">
       {jobs.map(card=>{
         return (
           <Card 
            id={card.id} 
            company={card.company} 
            logo={card.logo} 
            isNew={card.new} 
            isFeatured={card.featured}
            position={card.position}
            role={card.role}
            level={card.level}
            postedAt={card.postedAt}
            contract={card.contract}
            location ={card.location}
            languages={card.languages}
            tools={card.tools}
            filterThis={filterThis}
            jobs={jobs}

            />
         )
       })} 
      </div>
    </div>
  );
}

export default App;

这是 Card.js 组件:


const Card =({id, company, logo, isNew, isFeatured,  position, role, level, postedAt, contract, location, languages,tools, filterThis})=>{
    return (
        <div className="card">
            <img src={logo}/>
            <div className="main">
            <div className="highlights">
             <p className="company">{company}</p>

             <p className="new">{isNew?"NEW!":null}</p>
             <p className="featured">{isFeatured?"FEATURED":null}</p>    
            </div>

            <h3>{position}</h3>
             <div className="description">
             <p>{postedAt}</p>
             <p>{contract}</p>
             <p>{location}</p> 
             </div>

             </div>
             <div className="buttons">
                 <Button filterThis ={filterThis}  tools={tools}  languages={languages} role={role} level={level}/>
             </div>
        </div>
    )

}

export default Card;

Button.js 组件:


import React, { useState } from 'react';

const Button = ({role, jobs, level, languages, tools, filterThis}) =>{

    return (
        <div>
            <button value={role} onClick={(e)=>filterThis(e,"role")}>{role}</button>
            <button value={level} onClick={(e)=>filterThis(e,"level")}>{level}</button>

            {languages && languages.map(lang=>{
                return (
                <button value={lang} onClick={(e)=>filterThis(e,"languages", lang)}>{lang}</button>
                )
            })}
             {tools && tools.map(tool=>{
                return (
                <button value={tool} onClick={(e)=>filterThis(e,"tools")}>{tool}</button>
                )
            })}
        </div>
    )
}

export default Button;

以及我从中提取数据的 Data.js:

 {
    "id": 1,
    "company": "Photosnap",
    "logo": "/images/photosnap.svg",
    "new": true,
    "featured": true,
    "position": "Senior Frontend Developer",
    "role": "Frontend",
    "level": "Senior",
    "postedAt": "1d ago",
    "contract": "Full Time",
    "location": "USA Only",
    "languages": ["HTML", "CSS", "JavaScript"]
  },
  {
    "id": 2,
    "company": "Manage",
    "logo": "./images/manage.svg",
    "new": true,
    "featured": true,
    "position": "Fullstack Developer",
    "role": "Fullstack",
    "level": "Midweight",
    "postedAt": "1d ago",
    "contract": "Part Time",
    "location": "Remote",
    "languages": ["Python"],
    "tools": ["React"]
  },
  {
    "id": 3,
    "company": "Account",
    "logo": "./images/account.svg",
    "new": true,
    "featured": false,
    "position": "Junior Frontend Developer",
    "role": "Frontend",
    "level": "Junior",
    "postedAt": "2d ago",
    "contract": "Part Time",
    "location": "USA Only",
    "languages": ["JavaScript"],
    "tools": ["React", "Sass"]
  },

现在我可以在前端正确显示数据,并且可以成功过滤角色和级别。问题是试图映射那些嵌套数组“语言”和“工具”。我找不到映射和过滤它们的方法(在 Button 组件中我映射它们没有问题,但现在过滤是问题)。

希望我说清楚了,谢谢你们的帮助!

【问题讨论】:

  • 你能用这段代码做一个codesandbox,这样我可以更好地帮助你吗?
  • 你能附上一些截图你遇到什么问题吗?
  • 如果您收到过滤器的返回结果,它也会返回一个数组,因此您很可能必须映射过滤器返回或执行类似 lang[0] 或 tool[0] 的操作。
  • 我会尝试把代码沙箱放进去

标签: reactjs


【解决方案1】:

你可以这样做。
但无论如何,您都需要添加一个清除按钮来刷新您的默认对象。

import React, { useState } from "react";

import "./App.css";
// import { filter } from "async";
import Data from "./data.js";
import Card from "./Card";

function App() {
  const [jobs, setJobs] = useState(Data);

  const filterThis = (e, type) => {
    let categorySelected = e.target.value;
    const filteredData = JSON.parse(JSON.stringify(Data));

    if (type === "languages" || type === "tools") {
      let x = filteredData.filter(item => {
        if (typeof item[type] !== "undefined") {
          if (item[type].includes(e.target.value)) {
            return item;
          }
        }
      });
      setJobs(x);
    } else {
      setJobs(filteredData.filter(job => job[type] === categorySelected));
    }
  };

【讨论】:

  • 非常感谢!你能用几句话解释这段代码在做什么,这是否是通过嵌套数组映射时的最佳实践?
  • @ChirstianaEriksten 好吧,整个想法是在开始过滤之前克隆您的默认 Data 对象,其余的只是本机 javascript 函数。常量过滤数据 = JSON.parse(JSON.stringify(Data));获得过滤后的对象后,只需使用它设置状态即可。setJobs([]) 只要您将使用本机 javascript 函数并保持代码简洁易读,这是一个很好的做法。如果它真的是最好的,我想知道,但这就是我过滤该对象数组的方式。希望它有意义。
  • 太棒了,它确实很有意义。谢谢!
猜你喜欢
  • 1970-01-01
  • 2020-09-15
  • 1970-01-01
  • 2021-10-18
  • 1970-01-01
  • 2016-10-29
  • 2022-08-02
  • 1970-01-01
相关资源
最近更新 更多