Next.js 13+TypeScript开发TodoApp添加任务时触发tasks.map不是函数错误
修复Next.js 13 Todo应用中"tasks.map is not a function"错误
核心错误原因
你遇到的TypeError: tasks.map is not a function是因为AddItem函数里错误地将数组类型的tasks状态改成了字符串——执行setTasks(Item)时,Item是输入框的字符串值,导致后续渲染时tasks变成字符串,无法调用数组的map方法。
具体修复点及完整代码
修复AddItem函数的状态更新逻辑
- 不能直接引用原数组(
let temp = tasks是引用赋值,会污染原状态),要通过扩展运算符创建新数组副本 - 移除if语句末尾的分号,否则条件判断会失效
- 将
setTasks(Item)改为setTasks(temp),确保更新的是数组类型
- 不能直接引用原数组(
修正列表项的key值
- 任务项是字符串,没有
index属性,直接用task结合索引作为key(避免重复任务导致的key冲突)
- 任务项是字符串,没有
修正Input的提示属性
placeContent是布局属性,输入框提示应该用placeholder
修复后的完整代码:
"use client" import "./globals.css"; import { Button, Flex, ListItem, UnorderedList, Input } from "@chakra-ui/react"; import { useState } from "react"; export default function Home() { const [tasks, setTasks] = useState(["1", "2", "3"]); const [item, setItem] = useState(""); // 变量名改用小写开头,符合TS规范 function removeItem(taskName: string) { setTasks(tasks.filter(task => task !== taskName)); } function addItem() { // 参数未使用,直接移除 if (item.trim() !== "" && !tasks.includes(item)) { const temp = [...tasks]; // 创建数组副本 temp.push(item); setTasks(temp); setItem(""); } } return ( <Flex justifyContent="center" alignItems="center" width="100%" height="100vh" // 加上vh单位,确保垂直居中生效 flexDirection="column" gap={4} // 增加间距,布局更美观 > <UnorderedList spacing={3}> {tasks.map((task, index) => ( <ListItem key={`${task}-${index}`}> {task} <Button ml={4} onClick={() => removeItem(task)} colorScheme="red" > Remove Item </Button> </ListItem> ))} </UnorderedList> <Input placeholder="输入任务名称" value={item} onChange={(e) => setItem(e.target.value)} width="300px" /> <Button onClick={addItem} colorScheme="blue"> Add Item </Button> </Flex> ); }
额外优化:
- 变量名
Item改为item,符合TypeScript的小驼峰命名规范 - 给Flex加上
height="100vh",确保页面垂直居中生效 - 增加
gap和spacing属性优化布局间距 - 给按钮加上颜色主题,提升视觉体验
内容的提问来源于stack exchange,提问作者Psyco
相关产品推荐
相关产品推荐

