【问题标题】:Map function keeps repeating the output地图功能不断重复输出
【发布时间】:2020-08-11 01:21:03
【问题描述】:

我正在制作一个从 Country Api 获取数据的小型 React 应用程序。我想在 React 中使用 Select 标签。这样我就可以过滤页面上国家的地区。因此,如果有人选择欧洲,它会返回欧洲国家,或者非洲,然后是非洲国家,依此类推。我看过这篇文章以使用 select tag 。但是,我遇到的问题是列表不断重复。

以下是我目前的代码:

import React, { Component } from 'react';
import { CountryList } from './Components/Card-List/CountryList';
import { SearchBox } from './Components/Search-box/Search-Box';
import { NavBarCard }from './Components/NavBar/NavBarCard';
import './Countries.styles.css';


class Countries extends Component {
constructor() {
    super();
    this.state = {
        countries:[],
        searchField:"",
        regionField:"",
        darkMode: false
    }
    this.setDarkMode = this.setDarkMode.bind(this);
    // this.handleRegion = this.handleRegion.bind(this);
   };


componentDidMount() {
    fetch("https://restcountries.eu/rest/v2/all")
    .then(response => response.json())
    .then(all =>  this.setState({ countries: all,
        regions: all}))
}
setDarkMode(e){
    this.setState((prevState) => ({ darkMode: !prevState.darkMode }));
}

handleRegion = (e) => {
    this.setState({regionField: e.target.value})
}
render() {
    const { countries, searchField, regionField, darkMode } = this.state;
    const filterCountries = countries.filter((country) => country.name.toLowerCase().includes(searchField.toLowerCase()) &&
     country.region.toLowerCase().includes(regionField.toLowerCase()));

     return(

            <div className={darkMode ? "dark-mode" : "light-mode" }>

                 <NavBarCard handlechange={this.setDarkMode} moonMode={darkMode ? "moon fas fa-moon" : "moon far fa-moon"} darkMode={darkMode ? "dark-mode" : "light-mode"}/>


                <div className="Input">

                    < SearchBox type="search" placeholder="Search a Country" handlechange={e=> this.setState({
                        searchField: e.target.value })}
                        />

                        {/* < SearchBox type="regions" placeholder="Filter by Regions" handlechange={e=> this.setState({
                            regionField: e.target.value })}
                            /> */}
                        <select onChange={this.handleRegion}>
                            {countries.map(region => (
                                <option key={region.alpha2Code}>
                                    {region.region}
                                </option>
                            ))}
                        </select>

                </div>
                <CountryList countries={filterCountries} />

            </div>

       )
     }
   }

  export default Countries

不知道我错过了什么。任何帮助将不胜感激。

【问题讨论】:

    标签: javascript arrays reactjs api map-function


    【解决方案1】:

    很明显,您的问题不在于代码本身,而在于您处理数据的方式。您正在映射国家数组,因此每个国家/地区都有一个区域字段。您在选择标签中返回的是所有国家/地区,但不是显示它们的名称,而是显示它们所属的地区。

    【讨论】:

    • 哦,我明白了!感谢您的提醒。
    • 如果您想遍历国家/地区数组并检索地区的唯一名称,您可以执行以下操作:new Set(countries.map(country=&gt;country.region)).map(uniqueRegion=&gt; &lt;option&gt;....&lt;/option&gt;
    • 使用 Set 类型,您可以清理数组并仅取回其中的唯一值,这适合您的情况,因为您可能有一个包含 200 个国家/地区的数组,每个国家/地区都有一个像“美国”这样的地区, “欧洲”……重复了很多次
    • 你的意思是这样&lt;select onChange={this.handleRegion}&gt; new Set(countries.map(country=&gt;country.region)).map(uniqueRegion=&gt; &lt;option&gt;{region.region}&lt;/option&gt; &lt;/select&gt;
    • 对不起,我忘记了在映射 Set 类型之前需要将其转换为数组,所以代码是这样的:&lt;select onChange={this.handleRegion}&gt;{Array.from(new Set(countries.map(country=&gt;country.region))).map(uniqueRegion=&gt; &lt;option&gt;{uniqueRegion}&lt;/option&gt;)}&lt;/select&gt;
    【解决方案2】:

    您将国家/地区传递给此&lt;CountryList countries={filterCountries} /&gt;。 我希望您不要循环渲染此组件中的国家/地区。

    这个:

    <select onChange={this.handleRegion}>
        {countries.map(region => (
            <option key={region.alpha2Code}>
                {region.region}
            </option>
        ))}
    </select>
    

    是正确的但是你需要添加值属性&lt;select onChange {this.handleRegion} value={regionField}&gt;

    同时在handleRegion 方法的构造函数中取消注释与this 关键字的绑定。

    编辑

    let regions = [];
        fetch("https://restcountries.eu/rest/v2/all")
            .then(response => response.json())
            .then(all => {
                // Get unique regions here using Set
                let uniqueRegions = new Set();
                all.forEach(item => {
                    uniqueRegions.add(item.region);
                });
    
                for (item of uniqueRegions) {
                    regions.push(item);
                };
    
                this.setState({
                    countries: all,
                    regions: regions
                })
            });
    

    【讨论】:

    • 这并不能解决我的问题。正如丹尼尔所说,我正在绘制国家地图并显示其所属地区的所有名称(见上图)。他给了我一个解决方案,但它不起作用。
    • AltBrian,刚刚添加了一个过滤器来仅获取区域。希望对你有帮助
    • 如何添加过滤器来获取区域?感谢您的帮助 Isah Ohieku
    • 再看我的帖子,你会看到我在Edited之后添加的代码块。我用Set来实现的。
    猜你喜欢
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多