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

React购物清单开发报错:Cannot read properties of null (reading 'filter')求助

解决"Cannot read properties of null (reading 'filter')"错误

错误原因

应用首次加载时,localStorage.getItem('shoppinglist')返回null(未保存过数据),经JSON.parse转换后,items的初始状态为null。而null不是数组,无法调用filter方法,因此在Content组件的items={items.filter(...)}行触发报错。

解决方案

给useState的初始值添加空数组兜底,确保items始终为数组类型,让所有数组方法能正常执行。

修改初始状态代码:

const [items, setItems] = useState(JSON.parse(localStorage.getItem('shoppinglist')) || []);

逻辑说明

  • 当localStorage存有数据时,JSON.parse返回保存的数组,|| []不生效;
  • 当localStorage无数据时,JSON.parse(null)返回null,|| []将初始值替换为空数组,避免null引发的方法调用错误。

修改后的完整代码

import Header from './Header';
import SearchItem from './SearchItem';
import AddItem from './AddItem';
import Content from './Content';
import Footer from './Footer';
import { useState, useEffect } from 'react';

function App() {
  // 添加空数组兜底,确保items始终为数组
  const [items, setItems] = useState(JSON.parse(localStorage.getItem('shoppinglist')) || []);
  const [newItem, setNewItem] = useState('')
  const [search, setSearch] = useState('')

  console.log('before useEffect')

  useEffect(() => {
    console.log('inside useEffect')
  },[items])

  const setAndSaveItems = (newItems) => {
    setItems(newItems);
    localStorage.setItem('shoppinglist', JSON.stringify(newItems));
  }

  console.log('after useEffect')

  const addItem = (item) => {
    const id = items.length ? items[items.length - 1].id + 1 : 1;
    const myNewItem = { id, checked: false, item };
    const listItems = [...items, myNewItem];
    setAndSaveItems(listItems);
  }

  const handleCheck = (id) => {
    const listItems = items.map((item) => item.id === id ? { ...item, checked: !item.checked } : item);
    setAndSaveItems(listItems);
  }

  const handleDelete = (id) => {
    const listItems = items.filter((item) => item.id !== id);
    setAndSaveItems(listItems);
  }

  const handleSubmit = (e) => {
    e.preventDefault();
    if (!newItem) return;
    addItem(newItem);
    setNewItem('');
  }

  return (
    <div className="App">
      <Header title="Grocery List" />
      <AddItem
        newItem={newItem}
        setNewItem={setNewItem}
        handleSubmit={handleSubmit}
      />
      <SearchItem
        search={search}
        setSearch={setSearch}
      />
      <Content
        items={items.filter(item => ((item.item).toLowerCase()).includes(search.toLowerCase()))}
        handleCheck={handleCheck}
        handleDelete={handleDelete}
      />
      <Footer length={items.length} />
    </div>
  );
}

export default App;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 00:05:21