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

Next.js组件报TypeError: Cannot read properties of null (reading 'useState')

问题分析与修复方案

错误根源

  1. 客户端组件不能是异步函数:你的TodoList组件标记了"use client",属于客户端组件,但你将其定义为async function——React客户端组件不允许是异步函数(异步组件是Next.js服务器组件的特性),这会导致React无法正确初始化组件上下文,进而抛出useState读取null的错误。
  2. 渲染期间直接调用状态更新:组件顶层的if (todos) { setDisplayedTodos(todos); }是在渲染流程中直接调用setState,违反React渲染规则,会触发不必要的重渲染,甚至引发循环问题。

修复步骤

1. 移除组件的async标识,改用useEffect获取数据

客户端组件获取远程数据需通过useEffect钩子(或SWR、React Query等数据库),不能直接在组件顶层使用await。

2. 修正状态更新逻辑

将数据获取与状态更新移至useEffect中,避免在渲染阶段调用setState。

修复后的完整代码

"use client";

import fetchTodos from "@/lib/fetchTodos";
import { useState, useEffect } from "react";
import TodoItem from "./TodoItem";
import Filters from "./Filters";

export default function TodoList() {
  const [todos, setTodos] = useState<Todo[] | undefined>(undefined);
  const [displayedTodos, setDisplayedTodos] = useState<Todo[] | undefined>(undefined);

  // 组件挂载后获取数据
  useEffect(() => {
    const loadTodos = async () => {
      const fetchedData = await fetchTodos();
      setTodos(fetchedData);
      setDisplayedTodos(fetchedData);
    };
    loadTodos();
  }, []);

  const filterTodos = (filteredTodos: Todo[]) => {
    setDisplayedTodos(filteredTodos);
  };

  let content;
  if (!todos || todos.length === 0 || displayedTodos === undefined) {
    content = <p>No todos available</p>;
  } else {
    // reverse会修改原数组,先拷贝再反转
    const sortedTodos = [...displayedTodos].reverse();
    content = (
      <ul>
        {sortedTodos.map((todo) => (
          <TodoItem key={todo.id} todo={todo} />
        ))}
      </ul>
    );
  }

  return (
    <>
      <Filters todos={todos} filterFunction={filterTodos} />
      {content}
    </>
  );
}

额外优化点

  • 给列表项添加key属性:React列表渲染要求每个子项有唯一key,避免渲染警告与性能问题。
  • 避免直接修改状态数组:reverse()会直接修改原数组,通过扩展运算符[...displayedTodos]拷贝后再处理,防止意外污染状态数据。

内容的提问来源于stack exchange,提问作者Jehonatán Chávez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 03:48:25