【问题标题】:Filter components by the value of a select element按选择元素的值过滤组件
【发布时间】:2020-12-23 01:05:00
【问题描述】:

这是我在 Codesandbox https://codesandbox.io/s/filter-search-gxidc?file=/src/App.js 上的应用的链接,它只是一个组件 app.js

在 data.js 我有一个对象数组:

export const data = [
  {
    currencies: [{ code: "AFN", name: "Afghan afghani", symbol: "؋" }],
    languages: [
      { iso639_1: "ps", iso639_2: "pus", name: "Pashto", nativeName: "پښتو" },
      { iso639_1: "uz", iso639_2: "uzb", name: "Uzbek", nativeName: "Oʻzbek" },
      {
        iso639_1: "tk",
        iso639_2: "tuk",
        name: "Turkmen",
        nativeName: "Türkmen"
      }
    ],
    flag: "https://restcountries.eu/data/afg.svg",
    name: "Afghanistan",
    topLevelDomain: [".af"],
    capital: "Kabul",
    region: "Asia",
    subregion: "Southern Asia",
    population: 27657145,
    borders: ["IRN", "PAK", "TKM", "UZB", "TJK", "CHN"],
    nativeName: "افغانستان"
  },
  {
    currencies: [{ code: "EUR", name: "Euro", symbol: "€" }],
    languages: [
      {
        iso639_1: "sv",
        iso639_2: "swe",
        name: "Swedish",
        nativeName: "svenska"
      }
    ],
    flag: "https://restcountries.eu/data/ala.svg",
    name: "Åland Islands",
    topLevelDomain: [".ax"],
    capital: "Mariehamn",
    region: "Europe",
    subregion: "Northern Europe",
    population: 28875,
    borders: [],
    nativeName: "Åland"
  },
  {
    currencies: [{ code: "ALL", name: "Albanian lek", symbol: "L" }],
    languages: [
      { iso639_1: "sq", iso639_2: "sqi", name: "Albanian", nativeName: "Shqip" }
    ],
    flag: "https://restcountries.eu/data/alb.svg",
    name: "Albania",
    topLevelDomain: [".al"],
    capital: "Tirana",
    region: "Europe",
    subregion: "Southern Europe",
    population: 2886026,
    borders: ["MNE", "GRC", "MKD", "KOS"],
    nativeName: "Shqipëria"
  },
  {
    currencies: [{ code: "DZD", name: "Algerian dinar", symbol: "د.ج" }],
    languages: [
      { iso639_1: "ar", iso639_2: "ara", name: "Arabic", nativeName: "العربية" }
    ],
    flag: "https://restcountries.eu/data/dza.svg",
    name: "Algeria",
    topLevelDomain: [".dz"],
    capital: "Algiers",
    region: "Africa",
    subregion: "Northern Africa",
    population: 40400000,
    borders: ["TUN", "LBY", "NER", "ESH", "MRT", "MLI", "MAR"],
    nativeName: "الجزائر"
  },
  {
    currencies: [{ code: "USD", name: "United State Dollar", symbol: "$" }],
    languages: [
      {
        iso639_1: "en",
        iso639_2: "eng",
        name: "English",
        nativeName: "English"
      },
      {
        iso639_1: "sm",
        iso639_2: "smo",
        name: "Samoan",
        nativeName: "gagana fa'a Samoa"
      }
    ],
    flag: "https://restcountries.eu/data/asm.svg",
    name: "American Samoa",
    topLevelDomain: [".as"],
    capital: "Pago Pago",
    region: "Oceania",
    subregion: "Polynesia",
    population: 57100,
    borders: [],
    nativeName: "American Samoa"
  },
  {
    currencies: [{ code: "EUR", name: "Euro", symbol: "€" }],
    languages: [
      { iso639_1: "ca", iso639_2: "cat", name: "Catalan", nativeName: "català" }
    ],
    flag: "https://restcountries.eu/data/and.svg",
    name: "Andorra",
    topLevelDomain: [".ad"],
    capital: "Andorra la Vella",
    region: "Europe",
    subregion: "Southern Europe",
    population: 78014,
    borders: ["FRA", "ESP"],
    nativeName: "Andorra"
  },
  {
    currencies: [{ code: "AOA", name: "Angolan kwanza", symbol: "Kz" }],
    languages: [
      {
        iso639_1: "pt",
        iso639_2: "por",
        name: "Portuguese",
        nativeName: "Português"
      }
    ],
    flag: "https://restcountries.eu/data/ago.svg",
    name: "Angola",
    topLevelDomain: [".ao"],
    capital: "Luanda",
    region: "Africa",
    subregion: "Middle Africa",
    population: 25868000,
    borders: ["COG", "COD", "ZMB", "NAM"],
    nativeName: "Angola"
  }
];

我想在 app.js 中映射并显示每个国家/地区的信息(我做了这部分)

这是 app.js 中的代码

import React, { useState, useEffect } from "react";
import "./styles.css";
import { data } from "./data";

export default function App() {
  const [cuntries, setCountries] = useState([]);
  const [region, setRegion] = useState('');

  useEffect(()=>{
    setCountries(data)
  },[])

  function filterByRegion(event) {
    setRegion(event.target.value);
    handleSubmit()
    // event.preventDefault()
  }

  function handleSubmit(){
    const newArr = cuntries.filter(cunt=> cunt.region === region)
    setCountries(newArr)
  }
  

  console.log(region);
  console.log(cuntries);

  return (
    <div className="App">
      <h1>filtering</h1>
      <form onChange={filterByRegion}>
      <label>Filter by region:</label>
        <select name="regions" id="region-select" >
          <option value="">Chose a region</option>
          <option value="Africa">Africa</option>
          <option value="Americas">Americas</option>
          <option value="Asia">Asia</option>
          <option value="Oceania">Oceania</option>
          <option value="Polar">Polar</option>
        </select>
      </form>
      <div>
        {cuntries.map((country) => {
          return (
            <div key={country.name} className="country">
              <h3>{country.name}</h3>
              <h3>{country.nativeName}</h3>
              <h3>{country.region}</h3>
            </div>
          );
        })}
      </div>
    </div>
  );
}

在 app.js 中,我有一个包含区域的选择元素 我想过滤用于渲染每个国家/地区的数组,这样当我选择不同的区域时,map 方法会渲染该区域中的国家/地区

我尝试了一些解决方案,但都没有奏效。

再次链接到应用程序https://codesandbox.io/s/filter-search-gxidc?file=/src/App.js:0-1424

【问题讨论】:

  • App.js 中的一些拼写错误 - cuntries 而不是 countries

标签: javascript arrays reactjs filter react-hooks


【解决方案1】:

主要问题可能是setRegion 是异步处理的,因此一旦您尝试按handleSubmit 中的值进一步过滤,那么该值很可能不存在。请参阅下方对您的组件的建议修改。

首先是将onChange事件添加到select而不是form

<select name="regions" id="region-select" onChange={filterByRegion}>
    <option value="">Chose a region</option>
    <option value="Africa">Africa</option>
    <option value="Americas">Americas</option>
    <option value="Asia">Asia</option>
    <option value="Oceania">Oceania</option>
    <option value="Polar">Polar</option>
</select>

修改filterRegion,将值传递给handleSubmit

const filterByRegion = (event) => {
    const region = event.target.value

    // I would keep this state if you really need for other purposes
    setRegion(region) 

    handleSubmit(region)
}

然后我会使用.filter data 作为原始数组来查找值:

const handleSubmit = (regionValue) => {
    const newArr = data.filter(c => c.region === regionValue)
    setCountries(newArr)
}

请找到有效的 CodeSandbox here

+1 加法:

如果您想为您的国家/地区呈现未找到值的状态:

{cuntries && cuntries.length > 0 ?
     cuntries.map((country) => {
          return (
            <div key={country.name} className="country">
              <h3>{country.name}</h3>
              <h3>{country.nativeName}</h3>
              <h3>{country.region}</h3>
            </div>
          );
     })
     : <div>No value found</div>
}

因此,如果您的 countries 数组中没有值,您可以渲染一个 &lt;div&gt;,它表示没有找到值。

【讨论】:

  • 好的,我应该在哪里添加handleSumbit()函数作为事件监听器
  • CodeSandbox 这是更新链接
  • @AhmedEldawody 根据我在这里写的内容查看工作修改:codesandbox.io/s/filter-search-forked-jz4uj?file=/src/App.js 选择值后,下拉菜单就像魅力一样。
  • 我不想无礼,一切都很好。但是当我选择第一个选项(选择一个区域)时,什么都没有渲染
  • 谢谢 Norbitrial 先生。我从你身上学到了很多
猜你喜欢
  • 2021-09-29
  • 1970-01-01
  • 2021-01-31
  • 1970-01-01
  • 2017-08-06
  • 2016-09-04
  • 2017-07-22
  • 2011-11-09
  • 2023-03-17
相关资源
最近更新 更多