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

React中如何将多个对象类型state合并为单个数组并访问使用?

问题点梳理

  1. 两个异步请求返回时序不确定,没有监听两个数据的加载状态就直接合并,会出现缺数据的情况
  2. definition 初始类型为字符串,和后续要存储的对象数组类型不匹配
  3. 缺少请求错误、返回数据为空的边界处理,接口异常时会直接抛出JS报错
  4. 第二个axios配置存在笔误,dataResponse 应为标准属性 responseType

方案1:保留原有双state逻辑(推荐需要单独使用两个对象的场景)

代码修正

import { useState, useEffect } from 'react';
import axios from 'axios';

// 调整state定义,新增加载状态标识,definition改为数组类型
const [ourWord, setOurWord] = useState({key: 0, word: '', definition: '', isLoaded: false});
const [homophone, setHomophone] = useState({key: 1, word: '', definition: '', isLoaded: false});
const [definition, setDefinition] = useState([]);

// 第一个请求:获取初始词信息
useEffect( () => {
  axios({
    url: `https://api.dictionaryapi.dev/api/v2/entries/en/${startingWord}`,
  })
  .then(res => {
    if (res.data?.[0]) {
      setOurWord({
        key: 0,
        word: res.data[0].word,
        definition: res.data[0].meanings?.[0]?.definitions?.[0]?.definition || '暂无释义',
        isLoaded: true
      });
    } else {
      setOurWord(prev => ({...prev, isLoaded: true}))
    }
  })
  .catch(err => {
    console.error('初始词查询失败', err)
    setOurWord(prev => ({...prev, isLoaded: true}))
  })
}, [startingWord]) // 补充startingWord依赖,初始词变化时自动重新请求

// 第二个请求:获取同音字信息
useEffect( () => {  
  axios({
    url: 'https://api.datamuse.com/words',
    method: 'GET',
    responseType: 'json',
    params: {
      md: "d",
      rel_hom: startingWord,
    }
  }).then(res => {
    const wordWithDefinition = res.data.filter(item => item.defs);
    if (wordWithDefinition.length) {
      setHomophone({
        key: 1,
        word: wordWithDefinition[0].word, 
        definition: wordWithDefinition[0].defs[0] || '暂无释义',
        isLoaded: true
      })
    } else {
      setHomophone(prev => ({...prev, isLoaded: true}))
    }
  })
  .catch(err => {
    console.error('同音字查询失败', err)
    setHomophone(prev => ({...prev, isLoaded: true}))
  })
}, [startingWord]);

// 监听两个数据加载状态,完成后合并为数组
useEffect(() => {
  if (ourWord.isLoaded && homophone.isLoaded) {
    // 可根据需求过滤无有效内容的空对象
    const mergedList = [ourWord, homophone].filter(item => item.word)
    setDefinition(mergedList)
  }
}, [ourWord, homophone])

JSX使用示例

  • 按key获取指定对象:const target = definition.find(item => item.key === 0) 即可拿到初始词的对象
  • 列表渲染:
{definition.map(item => (
  <div key={item.key}>
    <p>*词汇:{item.word}</p>
    <p>释义:{item.definition}</p>
  </div>
))}

方案2:使用Promise.all简化逻辑(推荐不需要单独维护两个对象的场景)

无需维护三个state,直接并发请求、统一处理结果,代码更简洁:

import { useState, useEffect } from 'react';
import axios from 'axios';

const [definition, setDefinition] = useState([])

useEffect(() => {
  // 并发发起两个请求,全部返回后统一处理
  Promise.all([
    axios({url: `https://api.dictionaryapi.dev/api/v2/entries/en/${startingWord}`}),
    axios({
      url: 'https://api.datamuse.com/words',
      method: 'GET',
      responseType: 'json',
      params: {md: "d", rel_hom: startingWord}
    })
  ]).then(([wordRes, homophoneRes]) => {
    const mergedList = []
    // 处理初始词结果
    if (wordRes.data?.[0]) {
      mergedList.push({
        key: 0,
        word: wordRes.data[0].word,
        definition: wordRes.data[0].meanings?.[0]?.definitions?.[0]?.definition || '暂无释义'
      })
    }
    // 处理同音字结果
    const validHomophone = homophoneRes.data.filter(item => item.defs)
    if (validHomophone.length) {
      mergedList.push({
        key: 1,
        word: validHomophone[0].word,
        definition: validHomophone[0].defs[0] || '暂无释义'
      })
    }
    setDefinition(mergedList)
  }).catch(err => {
    console.error('请求失败', err)
  })
}, [startingWord])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 22:57:01