React useState Hook报错:'setTodo'未定义,请求排查指导
问题解决:React中setTodo未定义&列表子项缺少唯一key
一、搞定'setTodo' was used before it was defined错误
这个错误根本原因是变量声明顺序搞反了:你把useState的定义放在了onDelete和addTodo函数之后,但这两个函数里直接用到了todos和setTodo——在JS里,函数定义时会扫描内部用到的变量,此时这俩变量还没被声明,自然触发ESLint的no-use-before-define规则。
修复方法很简单:把useState的声明移到所有用到它的函数前面,也就是函数组件的最顶部位置。
同时顺便修正你addTodo里的逻辑bug:原代码中sno初始未赋值,if(sno==0)永远不成立,而且如果todos是空数组,todos[todos.length-1]会返回undefined,访问.sno直接报错。
修正后的核心代码片段:
function App() { // 先声明state,再定义依赖它的函数 const [todos, setTodo] = useState([ { sno: 1, title: "Attock", description: "collection of taxes" }, { sno: 2, title: "Jehlum", description: "Verification of taxes" }, { sno: 3, title: "Sangjhani", description: "staff authentication" } ]); let mytitle = "My-Todos-List" const onDelete=(todo)=>{ setTodo(todos.filter((e)=>{ return e!==todo; })) } const addTodo=(title,desc)=>{ console.log("Title and description is adding here",title,desc) // 修正sno的判断逻辑,避免空数组报错 const sno = todos.length === 0 ? 1 : todos[todos.length-1].sno + 1; const mytodo={ sno: sno, title:title, desc: desc } console.log(mytodo) setTodo([...todos,mytodo]) } // 下面的return部分保持不变 return ( <div> <Header title1={mytitle} searchBar={true}/> <AddTodo addtodo={addTodo}/> <Todos todos={todos} onDelete={onDelete}/> <Footer/> </div> ); }
二、解决“列表的所有子项必须拥有唯一key”警告
这个警告出现在Todos组件内部渲染列表的时候,React要求循环生成的子元素必须有唯一的key属性,用来识别每个元素的身份,避免渲染异常。
直接用你数据里的sno字段作为key就行(因为它是自增的唯一值),假设你的Todos组件代码是这样的,修改如下:
// Todos.js 示例代码 function Todos({ todos, onDelete }) { return ( <div> {todos.map((todo) => ( // 给每个子项添加唯一key,用todo.sno <TodoItem key={todo.sno} todo={todo} onDelete={onDelete} /> ))} </div> ) }
⚠️ 注意:别用数组索引index当key,除非你的列表完全静态不会增删排序,否则会导致React渲染出错。
额外说明
有人让你导入Component完全没必要,你用的是函数组件+Hook,保持原有的import React, { useState } from 'react'就够了。
内容的提问来源于stack exchange,提问作者fahad khurshid
相关产品推荐
相关产品推荐

