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

React数组映射渲染失败求助:组件无法正常渲染内容

数组映射无法渲染内容的排查问题

我尝试通过数组映射渲染若干卡片,父组件已获取到数据,但卡片始终无法渲染。为排查问题,我回归基础写法,不引入卡片组件,仅在父组件中渲染<h1>标签,同样无法生效。

父组件代码

export const Home = () => {

  const { store, actions } = useContext(Context);

  const data_types = Object.keys(store.results);

  useEffect(() => {
    for (let data_type of data_types) {
      actions.getData(data_type)
    } 
  }, []);

  return (
    <div className="text-center mt-5">
      {data_types.map((data_type) => {
        store.results[data_type].map((item, index) => {
          <div className="container mb-4">
            {console.log(index, item)}
            <h1>{item}</h1>
          </div>
        })
      })
      }
    </div>
  )
}

数据获取与存储逻辑

const getState = ({ getStore, getActions, setStore }) => {
    return {
        store: {
            results: {
                people: [],
                planets: [],
                starships: [],
                vehicles: [],
            }
        },
        actions: {
            getData: async (data_type) => {

                const local_results = JSON.parse(localStorage.getItem("results"));

                if (local_results !== null && local_results[data_type].length > 0) {
                    console.log(`The data type ${data_type} is already in local storage`)
                    let result = {}
                    result[data_type] = [...local_results[data_type]]
                    setStore({
                        results: {
                            ...getStore().results,
                            ...result
                        }
                    })
                    return
                } 

                const baseURL = `https://swapi.dev/api/${data_type}/`;
                try {                       
                    const response_1 = await fetch(`${baseURL}`);
                    const data_1 = await response_1.json();

                    const response_2 = await fetch(`${data_1.next}`);
                    const data_2 = await response_2.json();
                    
                    let result = {}
                    result[data_type] = [...data_1.results, ...data_2.results]

                    setStore({
                        results: {
                            ...getStore().results,
                            ...result
                        }
                    })
                    localStorage.setItem("results", JSON.stringify(getStore().results));
    
                } catch (error) {
                    console.log(`Error loading message from https://swapi.dev/api/${data_type}/`, error);
                }

            }
        }
    }
}

控制台情况

控制台能打印出index和item的内容,说明数据已存在,但DOM中无对应渲染。

尝试的React State改造代码

export const Home = () => {

  const { store, actions } = useContext(Context);

  const [arr, setArr] = useState([])

  const data_types = Object.keys(store.results);

  useEffect(() => {
    for (let data_type of data_types) {
      actions.getData(data_type)
    } 
    setArr(store.results);
  }, []);

  return (
    <div className="text-center mt-5">
      {data_types.map((data_type) => {
        arr !== "undefined" && data_type in arr ? arr[data_type].map((item, index) => {
          <div className="container mb-4">
            {console.log(index, item)}
            <h1>{item}</h1>
          </div>
        }) : null
      })
      }
    </div>
  )
}

问题原因与解决方法

1. 映射函数未返回JSX元素

你在map回调里直接写JSX,但没有用return返回,也没使用箭头函数的隐式返回(需用括号包裹JSX)。React要求map必须返回可渲染元素,否则不会生成DOM节点。

修复示例:

// 父组件中修改map部分
{data_types.map((data_type) => {
  // 返回内层map的结果
  return store.results[data_type].map((item, index) => {
    // 内层map返回JSX
    return (
      <div key={index} className="container mb-4">
        <h1>{item.name}</h1>
      </div>
    )
  })
})}

或用隐式返回简化:

{data_types.map((data_type) => 
  store.results[data_type].map((item, index) => (
    <div key={index} className="container mb-4">
      <h1>{item.name}</h1>
    </div>
  ))
)}

2. 直接渲染对象的问题

从控制台输出可知item是对象(如{name: "Luke Skywalker", ...}),直接<h1>{item}</h1>会渲染出[object Object],需访问对象具体属性(如item.name、item.height)才能显示预期内容。

3. 改造代码中的状态同步问题

useEffect里直接setArr(store.results)时,actions.getData是异步操作,此时store.results还是初始空数组,后续store更新也不会同步到arr(因为useEffect依赖为空数组,仅执行一次)。无需额外arr状态,直接使用store.results即可,store更新会触发组件重新渲染。

4. 缺少key属性

map渲染列表时,必须给每个元素添加唯一key属性,帮助React识别元素变化。可用数据中的唯一标识(如SWAPI返回的url),临时场景也可用index(不推荐动态列表)。

5. localStorage存储的异步问题

setStore是异步操作,原代码中getStore().results可能还是旧值,应使用更新后的结果存入localStorage:

const updatedResults = {...getStore().results, ...result}
setStore({ results: updatedResults })
localStorage.setItem("results", JSON.stringify(updatedResults));

最终修复后的父组件代码示例

export const Home = () => {
  const { store, actions } = useContext(Context);
  const data_types = Object.keys(store.results);

  useEffect(() => {
    data_types.forEach(data_type => actions.getData(data_type));
  }, []);

  return (
    <div className="text-center mt-5">
      {data_types.map((data_type) => (
        <div key={data_type} className="mb-5">
          <h2>{data_type.charAt(0).toUpperCase() + data_type.slice(1)}</h2>
          {store.results[data_type].map((item) => (
            <div key={item.url} className="container mb-4">
              <h1>{item.name}</h1>
            </div>
          ))}
        </div>
      ))}
    </div>
  );
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 00:20:17