next.js 奇怪的错误“TypeError:无法读取null的属性(阅读'useState')”

zlhcx6iw  于 2023-06-22  发布在  其他
关注(0)|答案(1)|浏览(139)

救命。我不知道怎么回事,但useState坏了。我正在创建一个下一个应用程序,不知何故useState应该是null。我不明白为什么,因为我是从react导入的,但是控制台抛出了这个错误“- error TypeError:无法读取null的属性(阅读'useState')"。这真的很奇怪,因为我只在一个组件中得到这个错误,而其他组件工作得很好。

"use client";

import fetchTodos from "@/lib/fetchTodos";

import { useState } from "react";

import TodoItem from "./TodoItem";
import Filters from "./Filters";

export default async function TodoList() {
  const todos = await fetchTodos();

  let content;

  const [displayedTodos, setDisplayedTodos] = useState<Todo[] | undefined>(undefined);

  if (todos) {
    setDisplayedTodos(todos);
  }

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

  if (!todos || todos.length === 0 || displayedTodos === undefined) {
    content = <p>No todos available</p>;
  } else {
    const sortedTodos = displayedTodos.reverse();

    content = (
      <ul>
        {sortedTodos.map((todo) => (
          <TodoItem todo={todo} />
        ))}
      </ul>
    );
  }

  // return content;

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

我已经试过安装一个更新版本的react,但它没有工作。
即使是像这样最简单的useState实现也会给予我同样的错误:

const [s, x] = useState();
zf9nrax1

zf9nrax11#

这是因为客户端功能组件应该是同步的。
所以你需要做的是删除async关键字,并在useEffect中异步获取数据:

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

export default function TodoList() {

  const [displayedTodos, setDisplayedTodos] = useState<Todo[] | undefined>(undefined);
  const [initialTodos, setInitialTodos] = useState<Todo[] | undefined>(undefined);
  
  const filterTodos = (filteredTodos: Todo[]) => {
    setDisplayedTodos(filteredTodos);
  };

  let content;

  if (!initialTodos || initialTodos.length === 0 || displayedTodos === undefined) {
    content = <p>No todos available</p>;
  } else {
    const sortedTodos = displayedTodos.reverse();

    content = (
      <ul>
        {sortedTodos.map((todo) => (
          <TodoItem todo={todo} />
        ))}
      </ul>
    );
  }

  // fetch data side effect

  useEffect(() => {
    const fetchMyTodos = async () => {
      const todos = await fetchTodos();
      setInitialTodos(todos);
      setDisplayedTodos(todos);
    }
    fetchMyTodos();
  },[])

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

相关问题