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

React新手调用API后页面返回空但console.log正常的问题

问题:React调用API后页面select为空但console显示内容正常

我是React新手,尝试调用API并处理结果后返回内容,但页面返回为空,然而console.log显示内容正常。我的console.log出现了三次调用,但页面上的select组件为空。

我的代码

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import Currencies from './TestApi';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Currencies />
    <App />
  </React.StrictMode>
);

reportWebVitals();

TestApi.js

import { useState, useEffect } from 'react';

function Currencies() {
    const API_URL = 'https://cdn.jsdelivr.net/gh/fawazahmed0/currency-api@1/latest/currencies.json';
    const [options, setOptions] = useState([]);

    useEffect(() => {
        const fetchOptions = async () => {
            try {
                const response = await fetch(`${API_URL}`);
                const data = await response.json();
                let optionsTmp = '';
                for (var key in data)
                {
                    optionsTmp = optionsTmp.concat('<option key="').concat(key).concat('">').concat(data[key]).concat('</option> ');
                }
                setOptions(optionsTmp);
            } catch(err) {
                console.log(err.message);
            }
        }

        fetchOptions();
    }, [options]);

    console.log(options);

    return (
        <select>
            {options}
        </select>
    );
}

export default Currencies;

问题原因及解决方案

核心问题1:HTML字符串无法被React解析为DOM元素

你现在是把拼接好的HTML字符串直接传给options状态,React在JSX中渲染字符串时会把它当作纯文本处理,不会解析成<option>标签,所以select看起来是空的(实际是显示了一串HTML文本,只是肉眼不可见)。

核心问题2:useEffect依赖错误导致无限循环

useEffect的依赖数组里包含了options,每次调用setOptions更新状态后,会再次触发useEffect执行,导致无限调用API和更新状态,这就是console.log出现三次调用的原因(React严格模式下还会额外执行一次)。

修改后的TestApi.js代码

import { useState, useEffect } from 'react';

function Currencies() {
    const API_URL = 'https://cdn.jsdelivr.net/gh/fawazahmed0/currency-api@1/latest/currencies.json';
    // 初始值保持数组,用来存储React元素
    const [options, setOptions] = useState([]);

    useEffect(() => {
        const fetchOptions = async () => {
            try {
                const response = await fetch(API_URL);
                const data = await response.json();
                // 遍历数据生成<option>元素数组,而非HTML字符串
                const optionsArr = Object.entries(data).map(([key, name]) => (
                    <option key={key} value={key}>{name}</option>
                ));
                setOptions(optionsArr);
            } catch(err) {
                console.log(err.message);
            }
        }

        fetchOptions();
    }, []); // 依赖数组设为空,仅在组件挂载时执行一次

    return (
        <select>
            {options}
        </select>
    );
}

export default Currencies;

关键修改点说明

  1. 生成React元素数组:用Object.entries遍历API返回的对象,把每个键值对转换成<option>组件,让React能正确识别并渲染这些元素。
  2. 修正useEffect依赖:将依赖数组改为空数组,确保API请求只在组件第一次挂载时执行一次,避免无限循环。
  3. 添加option的value属性:这是select组件的常规用法,方便后续获取用户选中的值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 13:35:07