React에서 객체 배열을 필터링하는 방법은 무엇입니까?

45242 단어 react
이전 기사에서 filter numbers and strings in React 방법을 설명했습니다. 이 기사에서는 객체 배열을 필터링하는 방법을 살펴봅니다.

프로젝트 설정



다음 명령을 사용하여 반응 앱을 만듭니다.

npx create-react-app react-filter-object-array

index.css에 다음 CSS를 추가합니다.

body {
  display: flex;
  justify-content: center;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  margin: 10px 0;
  border: 1px solid;
  padding: 10px;
}
.experience_filter {
  display: flex;
  gap: 6px;
  margin: 10px 0;
}
.experience_filter button {
  cursor: pointer;
  border: 1px solid;
  border-radius: 4px;
  padding: 4px;
  background-color: white;
}
.experience_filter button.selected {
  background-color: wheat;
}


다음 코드로 App.js를 업데이트합니다.

import { useState } from "react"

const employees = [
  {
    id: 1,
    name: "Tobe",
    experience: 4,
    department: "Accounting",
  },
  {
    id: 2,
    name: "Jolee",
    experience: 13,
    department: "Services",
  },
  {
    id: 3,
    name: "Muhammad",
    experience: 14,
    department: "Training",
  },
  {
    id: 4,
    name: "Hubie",
    experience: 5,
    department: "Sales",
  },
  {
    id: 5,
    name: "Yoshiko",
    experience: 16,
    department: "Services",
  },
  {
    id: 6,
    name: "Beatrix",
    experience: 17,
    department: "Human Resources",
  },
  {
    id: 7,
    name: "Jacob",
    experience: 4,
    department: "Engineering",
  },
  {
    id: 8,
    name: "Koren",
    experience: 4,
    department: "Accounting",
  },
  {
    id: 9,
    name: "Marissa",
    experience: 20,
    department: "Support",
  },
  {
    id: 10,
    name: "Rufe",
    experience: 18,
    department: "Training",
  },
]

function App() {
  const [filteredEmployees, setFilteredEmployees] = useState(employees)
  return (
    <div className="App">
      <ul>
        {filteredEmployees.map(employee => {
          const { name, experience, department, id } = employee
          return (
            <li key={id}>
              <div>
                Name: <strong>{name}</strong>
              </div>
              <div>Experience: {experience} year(s)</div>
              <div>Department: {department}</div>
            </li>
          )
        })}
      </ul>
    </div>
  )
}

export default App


여기에 10명의 직원 목록이 있고 우리는 그들을 통해 looping 있습니다.
각 직원의 정보를 카드에 표시합니다.


부서별 필터링



다음 기능을 사용하여 부서별로 직원을 필터링할 수 있습니다.

const filterByDepartment = department => {
  setFilteredEmployees(
    employees.filter(employee => {
      return employee.department === department
    })
  )
}


여기서 우리는 array filter function 을 사용하고 여기에 콜백을 전달합니다. 직원 배열의 각 항목에 대해 콜백이 호출됩니다. 콜백이 직원에 대해 true를 반환하면 해당 직원만 배열에 추가되고 필터 함수에 의해 반환됩니다. 반환된 배열을 filteredEmployees 상태로 설정하고 있습니다.

이제 고유한 부서를 나열하는 드롭다운을 추가해 보겠습니다.

import { useState } from "react"

const employees = [
  //...
]

function App() {
  const [filteredEmployees, setFilteredEmployees] = useState(employees)

  const filterByDepartment = department => {
    setFilteredEmployees(
      employees.filter(employee => employee.department === department)
    )
  }

  // Using Set to filter unique values
  const departments = Array.from(
    new Set(employees.map(employee => employee.department))
  )

  return (
    <div className="App">
      <select onChange={e => filterByDepartment(e.target.value)}>
        <option value="" disabled default selected>
          Select department
        </option>

        {departments.map(department => {
          return <option key={department}>{department}</option>
        })}
      </select>
      <ul>
        {filteredEmployees.map(employee => {
          const { name, experience, department, id } = employee
          return (
            <li key={id}>
              <div>
                Name: <strong>{name}</strong>
              </div>
              <div>Experience: {experience} year(s)</div>
              <div>Department: {department}</div>
            </li>
          )
        })}
      </ul>
    </div>
  )
}

export default App


이제 애플리케이션을 실행하고 부서를 선택하면 해당 부서의 직원만 표시됩니다.

여러 값 필터링



다른 필터를 추가해야 하는 경우 필터를 다른 상태로 저장하고 파일러가 변경될 때마다 useEffect hook 을 실행할 수 있습니다.

import { useEffect, useState } from "react"

const employees = [
  //..
]

function App() {
  const [filteredEmployees, setFilteredEmployees] = useState(employees)
  const [department, setDepartment] = useState()
  const [experience, setExperience] = useState()

  // Using Set to filter unique values
  const departments = Array.from(
    new Set(employees.map(employee => employee.department))
  )

  useEffect(() => {
    setFilteredEmployees(
      employees.filter(employee => {
        return (
          (!department || department === employee.department) &&
          (!experience ||
            (experience === "LESS_THAN_10"
              ? employee.experience < 10
              : employee.experience >= 10))
        )
      })
    )
  }, [department, experience])

  return (
    <div className="App">
      <select onChange={e => setDepartment(e.target.value)}>
        <option value="" disabled default selected>
          Select department
        </option>

        {departments.map(department => {
          return <option key={department}>{department}</option>
        })}
      </select>
      <div className="experience_filter">
        <button
          className={`${experience === "LESS_THAN_10" ? "selected" : ""}`}
          onClick={() => setExperience("LESS_THAN_10")}
        >
          Less than 10 years
        </button>
        <button
          className={`${experience === "10_PLUS" ? "selected" : ""}`}
          onClick={() => setExperience("10_PLUS")}
        >
          10+ years
        </button>
      </div>
      <ul>
        {filteredEmployees.map(employee => {
          const { name, experience, department, id } = employee
          return (
            <li key={id}>
              <div>
                Name: <strong>{name}</strong>
              </div>
              <div>Experience: {experience} year(s)</div>
              <div>Department: {department}</div>
            </li>
          )
        })}
        {filteredEmployees.length === 0 && (
          <div>No employees matching the filter</div>
        )}
      </ul>
    </div>
  )
}

export default App


위의 코드에서 경험을 기반으로 추가 필터를 추가했습니다.
사용자가 필터를 변경할 때마다 필터를 해당 상태로 저장합니다. 또한 필터가 변경될 때마다 useEffect를 실행합니다.

useEffect 내부에서 부서 필터와 경험치 필터가 적용되었는지 확인하고 있습니다. 특정 필터가 선택된 경우에만 필터를 적용할 수 있도록 not 체크( !department!experience )가 있습니다.

모든 필터 지우기



마지막으로 필터 지우기 버튼을 추가하여 모든 필터를 지웁니다.

import { useEffect, useState } from "react"

const employees = [
  //..
]

function App() {
  const [filteredEmployees, setFilteredEmployees] = useState(employees)
  const [department, setDepartment] = useState()
  const [experience, setExperience] = useState()

  // Using Set to filter unique values
  const departments = Array.from(
    new Set(employees.map(employee => employee.department))
  )

  useEffect(() => {
    setFilteredEmployees(
      employees.filter(employee => {
        return (
          (!department || department === employee.department) &&
          (!experience ||
            (experience === "LESS_THAN_10"
              ? employee.experience < 10
              : employee.experience >= 10))
        )
      })
    )
  }, [department, experience])

  const clearFilters = () => {
    setDepartment()
    setExperience()
  }

  return (
    <div className="App">
      <select onChange={e => setDepartment(e.target.value)}>
        <option value="" disabled default selected>
          Select department
        </option>

        {departments.map(department => {
          return <option key={department}>{department}</option>
        })}
      </select>
      <div className="experience_filter">
        <button
          className={`${experience === "LESS_THAN_10" ? "selected" : ""}`}
          onClick={() => setExperience("LESS_THAN_10")}
        >
          Less than 10 years
        </button>
        <button
          className={`${experience === "10_PLUS" ? "selected" : ""}`}
          onClick={() => setExperience("10_PLUS")}
        >
          10+ years
        </button>
      </div>
      <button onClick={clearFilters}>Clear All filters</button>
      <ul>
        {filteredEmployees.map(employee => {
          const { name, experience, department, id } = employee
          return (
            <li key={id}>
              <div>
                Name: <strong>{name}</strong>
              </div>
              <div>Experience: {experience} year(s)</div>
              <div>Department: {department}</div>
            </li>
          )
        })}
        {filteredEmployees.length === 0 && (
          <div>No employees matching the filter</div>
        )}
      </ul>
    </div>
  )
}

export default App


소스 코드 및 데모



소스 코드here를 다운로드하고 데모here를 볼 수 있습니다.

좋은 웹페이지 즐겨찾기