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

使用map()遍历数组/集合/列表时为何无法渲染内容?

问题:React 待办事项列表无法渲染内容

我经常遇到这个问题,但一直没找到合适的重复问题模板,大多是因为无关代码过多。本文将打造一个极简示例作为通用模板。

我有一个待办事项数组:

[
  { id: 1, task: "go to the grocery store", isDone: false },
  { id: 2, task: "walk the dog",            isDone: true  },
  { id: 3, task: "buy a present for John",  isDone: false },
]

该数组的来源无关紧要。

它可以是硬编码的:

const todos = [
  { id: 1, task: "go to the grocery store", isDone: false },
  { id: 2, task: "walk the dog",            isDone: true  },
  { id: 3, task: "buy a present for John",  isDone: false },
];

也可以来自服务器加载的静态文件:

import todos from "../data/todos.json";

还可以是Web API调用的结果:

useEffect(() => {
  fetch("https://api.example.com/v1.0/me/todo-items")
    .then(response => response.json())
    .then(todos => setTodos(todos))
}, []);

或者是用户在应用逻辑中创建的:

function handleAddTodoSubmit(e) {
  e.preventDefault();
  const todo = { id: nextID, task, isDone };
  setTodos(todos => [...todos, todo]);
  setNextID(nextID => nextID + 1);
  setAddTodoDialogOpen(false);
}

无论todos如何定义,以下代码都无法渲染待办事项:

function TodoList({ todos }) {
  return (
    <ul>
      {todos.map((todo) => {
        <li key={todo.id}>
          <pre>
            <ASCIICheckbox isChecked={todo.isDone} />
            {" "}
            {todo.task}
          </pre>
        </li>
      })}
    </ul>
  );
}

检查渲染后的结构可以看到,<ul>元素存在,但其中没有任何<li>元素。可运行下方代码片段自行测试:

const TODOS = [
  { id: 1, task: "go to the grocery store", isDone: false },
  { id: 2, task: "walk the dog",            isDone: true  },
  { id: 3, task: "buy a present for John",  isDone: false },
];

function ASCIICheckbox({ isChecked }) {
  const check = isChecked ? "x" : " ";

  return (
    <React.Fragment>[{check}]</React.Fragment>
  );
}

function TodoList({ todos }) {
  return (
    <ul>
      {todos.map((todo) => {
        <li key={todo.id}>
          <pre>
            <ASCIICheckbox isChecked={todo.isDone} />
            {" "}
            {todo.task}
          </pre>
        </li>
      })}
    </ul>
  );
}

function App() {
  return (
    <div>
      <h1>My todo list:</h1>
      <TodoList todos={TODOS} />
    </div>
  );
}

ReactDOM.createRoot(document.querySelector("#root")).render(<React.StrictMode><App /></React.StrictMode>);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="root"></div>

我期望渲染出3个任务,但实际并未显示。请问如何修复渲染逻辑,展示集合中的内容?


修复方案

问题出在map回调函数中:使用大括号{}包裹JSX时,没有显式返回该元素;箭头函数用大括号包裹代码块时,必须通过return语句返回值,否则默认返回undefined,导致<ul>没有子元素。

有两种修复方式:

方式1:添加显式return

function TodoList({ todos }) {
  return (
    <ul>
      {todos.map((todo) => {
        // 添加return返回JSX元素
        return (
          <li key={todo.id}>
            <pre>
              <ASCIICheckbox isChecked={todo.isDone} />
              {" "}
              {todo.task}
            </pre>
          </li>
        );
      })}
    </ul>
  );
}

方式2:使用隐式返回

将大括号替换为小括号,让箭头函数隐式返回JSX元素(多行JSX建议用小括号包裹,避免语法错误):

function TodoList({ todos }) {
  return (
    <ul>
      {todos.map((todo) => (
        <li key={todo.id}>
          <pre>
            <ASCIICheckbox isChecked={todo.isDone} />
            {" "}
            {todo.task}
          </pre>
        </li>
      ))}
    </ul>
  );
}

修复后,map会返回每个待办事项对应的<li>元素,<ul>即可正确渲染出3个任务项。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 17:21:07