打字稿反应中获取对象可能是 'undefined'

Getting Object is possibly 'undefined' in typescript react

我正在用 React 练习打字稿,并从我几天前创建的 API 中获取一些数据,API 工作正常,我在获取时为我的前端获取数据,但是当我尝试在该数据数组上使用 forEach 或 map 方法,但它抛出了一个错误: Object is possibly 'undefined'

interface Posts {
  _id: string
  title: string
  date: string
  text: string
  author_name: string
  published: boolean
  __v: number
}

const TextField = () => {
  const [posts, setPosts] = useState<Posts>()

  const fetchData = async () => {
    const result = await fetch("https://ed-blog-api.herokuapp.com/api/posts")
    const data = await result.json()
    const posts = data.posts
    setPosts(posts)
  }

  return (
    <div>
      <button onClick={fetchData}>Click</button>
      {posts.forEach((post: object) => {  // getting error here for posts
        console.log(post)
      })}
    </div>
  )
}

我觉得你的Posts接口其实是单个Post

的接口

所以:

interface Post {
  _id: string
  title: string
  date: string
  text: string
  author_name: string
  published: boolean
  __v: number
}

type Posts=Post[]

现在在这里,您不再需要将 post 键入 object。 Typescript 会自行推断。

    const TextField = () => {
  const [posts, setPosts] = useState<Posts|[]>([])

  const fetchData = async () => {
    const result = await fetch("https://ed-blog-api.herokuapp.com/api/posts")
    const data = await result.json()
    const posts = data.posts
    setPosts(posts)
  }

  return (
    <div>
      <button onClick={fetchData}>Click</button>
      {posts.forEach((post) => {  
        console.log(post)
      })}
    </div>
  )
}

但实际上那个错误的原因是 JavaScript 中 null 的类型也是对象!因此,如果您键入 object 形式的任何内容,则表示它可以是数组、对象或 null。如果为空,则不能使用它的任何属性。

回应

{
  "posts": [{
    "_id": "61514ba64209dbbaef9d05bb",
    "title": "Valorant Sucks",
    "date": "2021-09-27T04:40:05.001Z",
    "text": "Valorant Sucks a lot, everytime I got fuccking smurf, not even a single bullet registering and lots of bugs and bugs",
    "author_name": "Dev Chaudhary",
    "published": true,
    "__v": 0
  }]
}

作为您使用的响应,response.postsArray

所以你应该这样做。

const [posts, setPosts] = useState<Array<Posts>>([])

此外,

return (
    <div>
      <button onClick={fetchData}>Click</button>
      {posts.forEach((post) => {  // you don't need to use `object` as type.        
        console.log(post)
      })}
    </div>
  )

完整代码

interface Posts {
  _id: string;
  title: string;
  date: string;
  text: string;
  author_name: string;
  published: boolean;
  __v: number;
}

const TextField = () => {
  const [posts, setPosts] = useState<Posts[]>([]);

  const fetchData = async () => {
    const result = await fetch('https://ed-blog-api.herokuapp.com/api/posts');
    const data = await result.json();
    const posts = data.posts;
    setPosts(posts);
  };

  return (
    <div>
      <button onClick={fetchData}>Click</button>
      {posts.map((post: Posts, index: number) => {
        // getting error here for posts
        console.log(post);
        return <div key={index}>{JSON.stringify(post)}</div>;
      })}
    </div>
  );
};

使posts成为一个数组。然后就可以解决循环错误了。

const [posts, setPosts] = useState<Posts[]>([]);

我建议使用 map 而不是 forEach

{posts.map((post: Posts, index: number) => {
    console.log(post);
    return <div key={index}>{JSON.stringify(post)}</div>;
})}

或者(如果你只想输出组件)

{posts.map((post: Posts, index: number) => (
    <div key={index}>{JSON.stringify(post)}</div>
))}