You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React点击搜索按钮报错,如何修复并更新CountrySWR组件

问题修复方案

一、修复SearchForm组件的提交错误

你遇到的e.target is not a function错误,是因为在handleSubmit里错误地把表单DOM对象当成函数调用了。e.target是表单元素,要获取输入框的值有两种常用方式:

方式1:直接通过表单元素获取值

修改handleSubmit函数:

function handleSubmit(e) {
    e.preventDefault();
    // 正确获取输入框的值:通过表单的elements集合访问控件
    const query = e.target.elements.query.value.trim();
    if (query) { // 空值不更新,避免无效API请求
        setCountryName(query);
    }
}

方式2:改成受控组件(更符合React最佳实践)

给input添加value和onChange,实时绑定输入状态:

import { useState } from "react";
import CountrySWR from "./CountrySWR";

export default function SearchForm(){
    const [countryName, setCountryName] = useState("a");
    const [inputValue, setInputValue] = useState("");

    function handleSubmit(e) {
        e.preventDefault();
        const query = inputValue.trim();
        if (query) {
            setCountryName(query);
        }
    }

    return (
        <>
            <form onSubmit={handleSubmit}>
                <input 
                    name="query"
                    value={inputValue}
                    onChange={(e) => setInputValue(e.target.value)}
                />
                <button type="submit">Search</button>
            </form>
            <CountrySWR name={countryName}/>
        </>
    );
};

二、修复CountrySWR组件的潜在问题

除了提交错误,你的CountrySWR还有几个会导致运行错误或显示异常的问题:

1. 未定义变量length和txt

添加变量声明,并正确判断国家数量:

// 在isLoading判断后添加
let txt = '';
// 先确保countries存在再访问length
if (countries?.length > 1) {
    txt = `Territories in ${name}`;
} else if (countries?.length === 1) {
    txt = countries[0].name.common;
}

2. 样式拼写错误:columnns → columns

修复布局样式的拼写错误:

<div style={{ columns: "150px 6", padding: "10px", margin: '20px', width: 'fit-content'}}>

3. 错误的API字段访问

restcountries API返回的country.name是对象,没有special字段,直接渲染country.name会报错,改成显示官方名称:

// 替换原有的条件渲染
<p>Official Name: {country.name.official}</p>

4. 避免使用index作为key

用国家的唯一标识cca3作为key,列表更新时更稳定:

<div key={country.cca3} style={{margin: '20px', border:"1px solid gray", padding: '20px',
borderRadius: '10px', display: 'inline-block'}}>

5. 冗余的图片key

img标签不需要单独加key,父元素已经有唯一key,直接去掉即可:

<img src={country.flags.png} 
     alt={`Flag of ${country.name.common}`} 
     height={150}
     style={{margin: '10px',border: '1px solid gray'}}/>

三、完整修正后的CountrySWR代码

import useSWR from "swr";

const fetcher = (...args) => fetch(...args).then((res) => res.json());

export default function CountrySWR({name}){
    // 处理空name的情况,避免无效请求
    const url = name ? `https://restcountries.com/v3.1/name/${name}` : null;

    const {
        data : countries,
        error,
        isLoading,
    } = useSWR(url, fetcher);

    if(error) return <div className="failure">Failed to load data</div>;
    if(isLoading) return <div className="loading">Loading, please wait...</div>;
    // 处理无匹配结果的情况
    if(!countries || countries.length === 0) {
        return <div className="no-data">No countries found for "{name}"</div>;
    }

    let txt = '';
    if (countries.length > 1) {
        txt = `Territories in ${name}`;
    } else {
        txt = countries[0].name.common;
    }

    return(
        <div style={{ columns: "150px 6", padding: "10px", margin: '20px', width: 'fit-content'}}>
            <h2>{txt}</h2>
            {countries.map((country) => (
                <div key={country.cca3} style={{margin: '20px', border:"1px solid gray", padding: '20px',
                borderRadius: '10px', display: 'inline-block'}}>
                    <h4>{country.name.common}</h4>
                    <p>Population: {country.population.toLocaleString('en-US')}</p>
                    <p>Official Name: {country.name.official}</p>
                    <img src={country.flags.png} 
                         alt={`Flag of ${country.name.common}`} 
                         height={150}
                         style={{margin: '10px',border: '1px solid gray'}}/>
                </div>
            ))}
        </div>
    );
}

内容的提问来源于stack exchange,提问作者Andy Johnston

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 17:57:14