ReactJS中如何在<img>标签的src属性URL中传递参数?
问题分析与修复方案
我帮你找出了几个导致无效src和功能异常的问题,咱们一步步来修复:
1. 最核心的图片URL错误
你在调用readySRC时传递的是{city}(一个包含city属性的对象),但cityToCodeMatcher函数期望接收的是字符串类型的城市名称。这会导致code变成undefined,最终生成的URL是https://www.countryflags.io/undefined/shiny/64.png,自然是无效的。
修复:把<img src={readySRC({city})}改成<img src={readySRC(city)}>
2. 按钮点击逻辑的异步状态问题
setPrintCity是React的异步状态更新方法,所以在clickfn里刚执行setPrintCity(true),紧接着判断if(printCity)时,printCity还是原来的false,导致timeZone(city)根本不会被调用。
修复:直接在点击函数里调用timeZone(city),不需要依赖状态判断:
const clickfn = () => { setPrintCity(true); timeZone(city); // 直接调用时区接口,不用等状态更新 }
3. 初始useEffect调用的参数缺失
你的useEffect里调用timeZone()但没有传参数,会导致请求URL变成http://worldtimeapi.org/api/timezone/Asia/undefined,触发控制台错误。可以设置一个默认城市,比如初始加载时传"Kolkata":
useEffect(()=> { timeZone("Kolkata"); // 设置初始默认城市 },[])
4. 可选优化:处理未匹配的城市
如果用户输入的城市不在你的匹配列表里,cityToCodeMatcher会返回undefined,还是会生成无效URL。可以添加默认值或者空值处理:
const cityToCodeMatcher = (city) => { const cityCodeMap = { Kolkata: 'IN', Tokyo: 'JP' // 后续可以继续添加更多城市映射 }; return cityCodeMap[city]; // 未匹配时返回undefined,后续在readySRC里处理 }
修复后的完整代码
import React, {useState,useEffect} from 'react'; import { Button } from 'react-bootstrap'; const TimeZoneComponent = () => { const [data, setData] = useState([]); const [city,setCity] = useState(''); const [printCity, setPrintCity] = useState(false); const clickfn = () => { setPrintCity(true); timeZone(city); } async function timeZone(city) { // 处理空城市的情况,避免无效请求 if (!city) return; try { const response = await fetch(`http://worldtimeapi.org/api/timezone/Asia/${city}`); const json = await response.json(); setData(json); } catch (error) { console.error('请求时区数据失败:', error); } } useEffect(()=> { timeZone("Kolkata"); },[]) const mystr = JSON.stringify(data.datetime); console.log("city typed = "+city); const cityToCodeMatcher = (city) => { const cityCodeMap = { Kolkata: 'IN', Tokyo: 'JP' }; return cityCodeMap[city]; } const readySRC = (city) => { const code = cityToCodeMatcher(city); // 没有匹配到城市代码时,返回空字符串避免无效图片请求 if (!code) return ''; return `https://www.countryflags.io/${code}/shiny/64.png`; } return( <> <div className="timezone"> <div id="timezone-input"> <label>Type Asian City Here.. <br/> <input type="text" placeholder=" Type city here.." onChange={(event)=>setCity(event.target.value)}/> <br/> <Button className="timezone-button" onClick={clickfn} >Get Current DateTime</Button> </label> </div> {/* 只有点击按钮后才展示时间和国旗 */} {printCity && ( <> Date: {mystr?.slice(1,11)} <br/> Time: {mystr?.slice(12,20)} <br/> Timezone: {data.timezone} <div> {/* 只有存在有效URL时才渲染图片 */} {readySRC(city) && <img src={readySRC(city)} alt="Country flag"/>} </div> </> )} </div> </> ); } export default TimeZoneComponent;
额外说明
- 我添加了
try/catch来处理fetch请求的错误,避免控制台报错影响后续功能 - 用
printCity状态控制信息展示,只有点击按钮后才显示日期时间和国旗 - 当没有匹配到城市代码时,不会渲染img标签,避免出现无效图片的占位符
内容的提问来源于stack exchange,提问作者MagnusEffect
相关产品推荐
相关产品推荐

