首页 > 解决方案 > 反应按钮以显示元素

问题描述

我正在从 Restcountries API 中提取国家,如果数组的当前状态有多个国家或少于或等于十个国家,我想列出国家名称以及每个国家旁边的“显示”按钮。显示按钮应显示我的Country函数的返回(渲染)中的内容。在App函数中,我为名为 的按钮编写了一个处理程序handleViewButton。我对如何在条件语句中过滤Countries函数中的元素以显示. 我尝试传递给该函数,但出现错误“未捕获的 TypeError:newSearch.toLowerCase 不是函数”。我真的只想触发该功能以显示按下的国家/地区按钮。elseCountryhandleViewButtonButtonCountry

应用程序.js

import React, { useState, useEffect } from 'react';
import './App.css';
import axios from 'axios';

const Country = ({country}) => {
    return (
        <>
            <h2>{country.name}</h2>
                <p>capital {country.capital}</p>
                <p>population {country.population}</p>
            <br/>
            <h3>languages</h3>
                {country.languages.map(language => <li key={language.name}>{language.name}</li>)}
            <br/>
            <img src={country.flag} alt="country flag" style={{ width: '250px'}}/>
        </>
    );
}

const Countries = ({countries, handleViewButton}) => {    
    const countriesLen = countries.length;
    console.log(countriesLen)

    if (countriesLen === 0) {
        return (
           <p>Please try another search...</p>
        );
    } else if (countriesLen === 1) {
        return (
           <ul>
                {countries.map((country, i) => <Country key={i} countriesLen={countriesLen} country={country}/>)}
           </ul>
        );
    } else if (countriesLen > 10) {
        return (
            <div>
                <p>Too many matches, specify another filter</p>
            </div>
        );
    } else {
        return (
            <ul>
                {countries.map((country, i) => <li key={i}>{country.name}<Button handleViewButton={handleViewButton}/></li>)}
            </ul>
        )
    };
};

const Button = ({handleViewButton}) => {
    return (
        <button onClick={handleViewButton}>Show</button>
    );
};

const Input = ({newSearch, handleSearch}) => {
    return (
        <div>
            find countries <input value={newSearch} onChange={handleSearch}/>
        </div>
    );
};

function App() {
    const [countries, setCountries] = useState([]);
    const [newSearch, setNewSearch] = useState('');

    const handleSearch = (event) => {
        const search = event.target.value;
        setNewSearch(search);
    };

    const handleViewButton = (event) => {
        const search = event.target.value;
        setNewSearch(countries.filter(country => country === search));
    };

    const showCountrySearch = newSearch
        ? countries.filter(country => country.name.toLowerCase().includes(newSearch.toLowerCase()))
        : countries;

    useEffect(() => {
        axios
            .get('https://restcountries.eu/rest/v2/all')
            .then(res => {
                setCountries(res.data);
                console.log('Countries array loaded');
            })
            .catch(error => {
                console.log('Error: ', error);
            })
    }, []);

    return ( 
        <div>
            <Input newSearch={newSearch} handleSearch={handleSearch}/>
            <Countries countries={showCountrySearch} handleViewButton={handleViewButton}/>
        </div>
    );
};

export default App;

在此处输入图像描述

标签: reactjs

解决方案


您可以使用 adisplayCountry来处理应显示的国家/地区。大多数情况下,您会使用 id,但我在这里使用country.name它是因为它应该是唯一的。

然后,您将使用matchedCountry查找您的国家/地区列表。

之后, aonHandleSelectCountry选择一个给定的国家。如果它已经被选中,那么你可以设置null为取消选择。

最后,您将有条件地呈现您的matchedCountry

const Countries = ({countries}) => {
    const [displayCountry, setDisplayCountry] = useState(null); 
    const countriesLen = countries.length;
    
    const matchedCountry = countries.find(({ name }) => name === displayCountry); 

    const onHandleSelectCountry = (country) => {
      setDisplayCountry(selected => { 
        return selected !== country.name ? country.name : null
      })
    }


    if (countriesLen === 0) {
        return (
           <p>Please try another search...</p>
        );
    } else if (countriesLen === 1) {
        return (
           <ul>
                {countries.map((country, i) => <Country key={i} countriesLen={countriesLen} country={country}/>)}
           </ul>
        );
    } else if (countriesLen > 10) {
        return (
            <div>
                <p>Too many matches, specify another filter</p>
            </div>
        );
    } else {
        return (
          <>
            <ul>
                {countries.map((country, i) => <li key={i}>{country.name}<Button handleViewButton={() => onHandleSelectCountry(country)}/></li>)}
            </ul>
            { matchedCountry && <Country countriesLen={countriesLen} country={matchedCountry}/> }
          </>
        )
    };
};

推荐阅读