React类组件实现用户筛选功能出现toLowerCase未定义报错排查
React 类组件实现用户导航筛选功能的报错修复
核心报错现象
控制台抛出错误:TypeError: Cannot read property 'toLowerCase' of undefined,同样的筛选逻辑使用Hooks实现时运行正常,切换为类组件后触发异常。
问题根因定位
- 构造函数状态被意外覆盖:原代码在constructor中连续两次为
this.state赋值,第二次的赋值操作会完全覆盖第一次写入的所有状态值,原本初始化的search、clicked、token字段全部丢失。后续调用this.state.search.toLowerCase()时,因为this.state.search本身是undefined,直接触发报错。 - 数组筛选逻辑不符合API要求:
Array.filter()的回调函数需要返回布尔值来决定条目是否保留,原代码在search为空时返回空字符串、匹配时返回对象/用户实体,逻辑完全不符合filter的执行规则;同时回调内存在未定义的users变量引用、错误判断user.length(普通用户对象不存在length属性)的问题。 - 缺少必填字段兜底判断:接口返回的用户数据如果存在
name字段缺失的情况,直接调用user.name.toLowerCase()也会触发同类报错。
修正后的实现代码
import React, { Component } from "react"; import "./Navbar.css"; export default class Navbar extends Component { constructor(props) { super(props); // 所有状态统一初始化,避免重复赋值覆盖 this.state = { clicked: false, token: this.props.token, search: "", loading: true, users: [] }; } menuClick = () => { this.setState({ clicked: !this.state.clicked }); }; componentDidMount() { fetch("/api/v1/user") .then(resp => resp.json()) .then(json => { this.setState({ loading: false, users: json.data || [] }); }) .catch(err => { this.setState({ loading: false }); console.error("用户列表加载失败:", err); }); } render() { const { users, loading, search } = this.state; let list = <div>LOADING</div>; if (!loading && Array.isArray(users) && users.length > 0) { list = users .filter(user => { // 搜索词为空时展示全部用户 if (search.trim() === "") return true; // 字段存在性兜底,避免undefined触发报错 const userName = user?.name?.toLowerCase() || ""; const searchKey = search.toLowerCase(); return userName.includes(searchKey); }) .map(user => ( <a key={user.id}> {user.name} {user.surname} </a> )); } else if (!loading) { list = "Error with loading"; } return ( <nav className="NavbarItems"> <ul> <li> <a className="item search"> <input className="srch-input" onChange={(e) => this.setState({ search: e.target.value })} type="text" placeholder="Szukaj" /> <a className="srch-btn" href="#"> <i className="fas fa-search"></i> </a> </a> </li> <li>{list}</li> </ul> </nav> ); } }
关键修正点说明
- 合并两次重复的state初始化逻辑,避免状态被覆盖丢失
- 修正filter回调的返回值逻辑,符合数组方法的执行规范
- 加入可选链做字段存在性兜底,从根源上避免undefined触发的方法调用报错
- 补充fetch请求的异常捕获逻辑,避免接口异常导致状态未更新
- 修正JSX中原生生
class属性的使用规范,替换为className消除语法警告 - 为map渲染的列表元素补充
key属性,符合React渲染列表的要求 - 移除未使用的冗余导入,精简代码体积
内容的提问来源于stack exchange,提问作者dirmane
相关产品推荐
相关产品推荐

