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

Next.js中使用useState无法设置API响应数据问题求助

问题:React useState更新后状态不生效,打印始终为空数组

编写了从API请求获取数据的函数,希望将获取到的数据存入useState声明的状态变量中,但始终无法生效,打印names和addresses时一直显示空数组。

用户提供的代码:

export default function Buttons({setOptionButtons, sendMessage, places}){

    const [data, setData] = useState(null)
    const [loading, setLoading] = useState(false)
    const [error, setError] = useState(null)
    const [names, setNames] = useState([])
    const [addresses, setAddresses] = useState([])

    useEffect(()=>{
        console.log(data)
    }
    ,[data])

    const pressOption = (input, option) => {
        const fetchData = async () => {
            for (const place of option){
                setLoading(true);
                try {
                    const requests = option.map((place) =>
                        axios.get(`url`)
                    );

                    const responses = await Promise.all(requests);
                    console.log(responses)
                    const items = responses.flatMap((response) => response.data.result.items);
                    const newNames = items.map((item) => item.name);
                    const newAddresses = items.map((item) => item.address_name);

                    setNames((prevNames) => [...prevNames, ...newNames]);
                    setAddresses((prevAddresses) => [...prevAddresses, ...newAddresses]);
                    setError(null);
                    console.log('Hello');
                    console.log(names)
                } catch(error) {
                    setError(error.message)
                } finally {
                    setLoading(false)
                }
            }
        };

        fetchData();
        setOptionButtons(false);
        sendMessage(input);
    }
    return (
///html code
    )
}

问题原因及修复方案

1. 状态更新的异步特性

React的setState是异步批量更新的,调用setNames/setAddresses后,当前函数作用域内的names/addresses还是旧值,所以立刻打印看不到最新数据。要查看最新状态,需要通过useEffect监听状态变化:

useEffect(() => {
  console.log('最新names:', names);
  console.log('最新addresses:', addresses);
}, [names, addresses]);

2. 多余的循环导致重复请求

代码中fetchData里的for (const place of option)完全多余——里面已经用option.map发起了所有place的请求,这个循环会让你重复发起option.length次全部请求,既浪费资源又会重复更新状态。直接删除这个for循环即可。

3. 未使用的冗余状态

代码里的data状态从未被更新,对应的useEffect也没有实际作用,可以直接删除;如果需要存储API返回的原始items,也可以在获取到items后用setData(items)更新它。

修复后的完整代码

export default function Buttons({setOptionButtons, sendMessage, places}){

    const [loading, setLoading] = useState(false)
    const [error, setError] = useState(null)
    const [names, setNames] = useState([])
    const [addresses, setAddresses] = useState([])

    // 监听names和addresses的变化,打印最新状态
    useEffect(() => {
        console.log('最新names:', names);
        console.log('最新addresses:', addresses);
    }, [names, addresses])

    const pressOption = (input, option) => {
        const fetchData = async () => {
            setLoading(true);
            try {
                // 发起所有请求
                const requests = option.map((place) =>
                    axios.get(`url`) // 注意替换成实际API地址
                );

                const responses = await Promise.all(requests);
                const items = responses.flatMap((response) => response.data.result.items);
                const newNames = items.map((item) => item.name);
                const newAddresses = items.map((item) => item.address_name);

                // 用函数式更新确保依赖最新的前序状态
                setNames((prevNames) => [...prevNames, ...newNames]);
                setAddresses((prevAddresses) => [...prevAddresses, ...newAddresses]);
                setError(null);
            } catch(error) {
                setError(error.message)
            } finally {
                setLoading(false)
            }
        };

        fetchData();
        setOptionButtons(false);
        sendMessage(input);
    }
    return (
        // 你的HTML代码
    )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 09:07:37