我無法弄清楚如何過濾我在前端導師中找到的這個職位串列。
過濾部分起作用。例如,如果我添加 HTML 和 Senior 標簽,它會正確過濾它。但是邏輯不正確,因為我對其他標簽進行了測驗,結果沒有按預期出現。
我很感激任何幫助指向正確的方向。
這是我的 App.js 代碼
import './App.css';
import axios from 'axios';
import React, {useState,useEffect} from "react";
import Card from "./components/card/Card";
import Header from "./components/header/Header";
import FilterBar from "./components/FilterBar/FilterBar";
function App() {
const [data, setData] = useState([]);
const URL = 'http://localhost:3000/data.json';
const [category, setCategory] = useState([]);
console.log("category is " category);
useEffect(() => {
axios.get(URL).then((response) => {
setData(response.data);
//console.log(data);
});
}, []);
/*useEffect(() => {
}, []);*/
function addItem(item){
console.log("addItem " item);
const duplicateItem = category.find((collection) => collection === item);
if(!duplicateItem){
setCategory([...category, item]);
} else {
alert(item " is already in the list.");
}
}
function removeAllItems(items, counter){
if(counter > 0){
setCategory(items);
} else {
alert("There are no items in the filter bar to remove.");
}
}
return (
<div className="App">
<Header />
{
category.length > 0 ?
<FilterBar removeAllItems={removeAllItems} languages={category} />
:
""
}
{
Object.keys(data).map((item, index) => (
category.length < 1 ?
<Card
key={index}
data_company_name={data[item].company}
data_logo={data[item].logo}
data_new={data[item].new}
data_featured={data[item].featured}
data_position={data[item].position}
data_languages={data[item].languages}
data_level={data[item].level}
data_role={data[item].role}
data_posted_at={data[item].postedAt}
data_contract={data[item].contract}
data_location={data[item].location}
data_tools={data[item].tools}
addItem={addItem}
/>
: category.includes(data[item].level)
|| category.includes(data[item].role)
|| category.every((language) => data[item].languages.includes(language))
|| category.every((tool) => data[item].tools.includes(tool))
?
<Card
key={index}
data_company_name={data[item].company}
data_logo={data[item].logo}
data_new={data[item].new}
data_featured={data[item].featured}
data_position={data[item].position}
data_languages={data[item].languages}
data_level={data[item].level}
data_role={data[item].role}
data_posted_at={data[item].postedAt}
data_contract={data[item].contract}
data_location={data[item].location}
data_tools={data[item].tools}
addItem={addItem}
/>
: ""
))}
</div>
);
}
export default App;
這是 Card.js
import {StyledCard} from './Card.styled';
const Card = ({addItem, data_logo, data_company_name, data_new, data_featured, data_position, data_languages, data_level, data_role, data_contract, data_posted_at, data_location, data_tools}) => {
const data = data_languages.map( (language, index) => {
return <span onClick={() => addItem(language) } key={index} className={`role-tag-${index}`}>{language}</span>;
});
const tools_data = data_tools.map( (tool, index) => {
return <span key={index} onClick={() => addItem(tool) } className={`data-tools`}>{tool}</span>
});
return (
<>
<div className={`card-container`}>
<StyledCard>
<div className={`inside-card-wrapper`}>
<div className={`img`}>
<img src={data_logo} alt=""/>
<div className={`company-tag-wrapper`}>
<span className={`company-name`}>{data_company_name}</span>
{
data_new === true ?
<span className={`job-tag-new`}>NEW!</span>
:
""
}
{
data_featured === true ?
<span className={`job-tag-featured`}>FEATURED</span>
:
""
}
<div className={`role-title`}>
<div><strong>{data_position}</strong></div>
<div className={`role-tags`}>
<span onClick={() => addItem(data_role)} className={`data-role`}>{data_role}</span>
<span onClick={() => addItem(data_level) } className={`data-level`}>{data_level}</span>
{data}
{tools_data}
</div>
</div>
<div className={`job-type-wrapper`}>
<div className={`post`}>
<span>{data_posted_at}</span>
•
<span>{data_contract}</span>
•
<span>{data_location}</span>
</div>
</div>
</div>
</div>
</div>
</StyledCard>
</div>
</>
);
};
export default Card;
這是 FilterBar.js 檔案
import {StyledFilterBar} from "./FilterBar.styled";
const FilterBar = ({removeAllItems, languages}) => {
//console.log("FilterBar.js " items);
let counter = 0;
const data = languages.map( (item, index) => {
counter = languages.length;
return <div key={index}>{item} </div>
});
return (
<div>
<StyledFilterBar>
<div className={`filter-options`}>
<div className={`left-side`}>
{data}
</div>
<div className={`right-side`}>
<div onClick={() => removeAllItems([], counter) } className={`clear`}>clear</div>
</div>
</div>
</StyledFilterBar>
</div>
);
};
export default FilterBar;
這是包含資料的 json 檔案
[
{
"id": 1,
"company": "Photosnap",
"logo": "./img/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"],
"tools": []
},
{
"id": 2,
"company": "Manage",
"logo": "./img/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": "./img/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"]
},
{
"id": 4,
"company": "MyHome",
"logo": "./img/myhome.svg",
"new": false,
"featured": false,
"position": "Junior Frontend Developer",
"role": "Frontend",
"level": "Junior",
"postedAt": "5d ago",
"contract": "Contract",
"location": "USA Only",
"languages": ["CSS", "JavaScript"],
"tools": []
},
{
"id": 5,
"company": "Loop Studios",
"logo": "./img/loop-studios.svg",
"new": false,
"featured": false,
"position": "Software Engineer",
"role": "Fullstack",
"level": "Midweight",
"postedAt": "1w ago",
"contract": "Full Time",
"location": "Worldwide",
"languages": ["JavaScript"],
"tools": ["Ruby", "Sass"]
},
{
"id": 6,
"company": "FaceIt",
"logo": "./img/faceit.svg",
"new": false,
"featured": false,
"position": "Junior Backend Developer",
"role": "Backend",
"level": "Junior",
"postedAt": "2w ago",
"contract": "Full Time",
"location": "UK Only",
"languages": ["Ruby"],
"tools": ["RoR"]
},
{
"id": 7,
"company": "Shortly",
"logo": "./img/shortly.svg",
"new": false,
"featured": false,
"position": "Junior Developer",
"role": "Frontend",
"level": "Junior",
"postedAt": "2w ago",
"contract": "Full Time",
"location": "Worldwide",
"languages": ["HTML", "JavaScript"],
"tools": ["Sass"]
},
{
"id": 8,
"company": "Insure",
"logo": "./img/insure.svg",
"new": false,
"featured": false,
"position": "Junior Frontend Developer",
"role": "Frontend",
"level": "Junior",
"postedAt": "2w ago",
"contract": "Full Time",
"location": "USA Only",
"languages": ["JavaScript"],
"tools": ["Vue", "Sass"]
},
{
"id": 9,
"company": "Eyecam Co.",
"logo": "./img/eyecam-co.svg",
"new": false,
"featured": false,
"position": "Full Stack Engineer",
"role": "Fullstack",
"level": "Midweight",
"postedAt": "3w ago",
"contract": "Full Time",
"location": "Worldwide",
"languages": ["JavaScript", "Python"],
"tools": ["Django"]
},
{
"id": 10,
"company": "The Air Filter Company",
"logo": "./img/the-air-filter-company.svg",
"new": false,
"featured": false,
"position": "Front-end Dev",
"role": "Frontend",
"level": "Junior",
"postedAt": "1mo ago",
"contract": "Part Time",
"location": "Worldwide",
"languages": ["JavaScript"],
"tools": ["React", "Sass"]
}
]
uj5u.com熱心網友回復:
問題是您將所有“類別”組合到一個過濾器中,但每個類別(語言、工具等)都有不同的匹配標準。我認為您想要的匹配標準是:
- 作業級別或作業角色的任何匹配項
- 工具和語言都匹配
但是如果不知道每個類別的過濾器型別,您就無法做到這一點。
所以,有幾種方法可以解決這個問題。一種方法是按類別分離過濾器。您可以撰寫一個自定義掛鉤來完成繁重的作業:
const createEmptyFilter = () => ({
all: new Set(),
language: new Set(),
tool: new Set(),
role: new Set(),
level: new Set()
});
const useFilter = () => {
const [filter, setFilter] = useState(createEmptyFilter);
const handleAddFilter = (type, value) => {
if (!filter[type]) {
alert(`Unknown filter category: '${type}'`);
return;
}
setFilter((prev) => {
const next = { ...prev };
next.all = new Set(prev.all).add(value);
next[type] = new Set(prev[type]).add(value);
return next;
});
};
const handleClearFilter = () => setFilter(createEmptyFilter());
const matchesFilter = (item) => {
const { language, tool, role, level } = filter;
if (level.size && !level.has(item.level)) return false;
if (role.size && !role.has(item.role)) return false;
for (const l of language) {
if (!item.languages.includes(l)) return false;
}
for (const t of tool) {
if (!item.tools.includes(t)) return false;
}
return true;
};
return [
[...filter.all.values()],
handleAddFilter,
handleClearFilter,
matchesFilter
];
};
有幾點需要注意:
- “全部”類別只是為了維護用戶將條目添加到過濾器的專案的順序。您可以通過組合所有類別的值來組合它,但您會失去排序。
- 現在我們知道每個過濾器屬于哪個類別,我們的過濾條件可以更具體。
使用該卡,您必須在應用過濾器時添加類別,例如:
<span
onClick={() => onAddFilter("role", data_role)}
className={`data-role`}
>
這是一個更新的示例。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/504585.html
