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
相关产品推荐
相关产品推荐

