reactjs - typescript / react : "Object is possibly ' null'"

标签 reactjs typescript fetch react-typescript

我正在将 React 组件更改为 Typescript。它调用一个 API。我相信我的接口(interface)设置正确,但我没有正确传递类型。
如何修复下面父级中的两个错误?

  • return <div>Error: {error.message}</div>; // "Object is possibly 'null'"
  • {stories.results.map((story, idx) => { // "Object is possibly 'null' or 'undefined'"
  • alt={ // Type 'string | null' is not assignable to type 'string | undefined'. Type 'null' is not assignable to type 'string | undefined'.

  • 我的界面

    export interface NewsProps {
      results?: (ResultsEntity)[] | null;
    }
    export interface ResultsEntity {
      section: string;
      title: string;
      abstract: string;
      url: string;
      multimedia?: (MultimediaEntity)[] | null;
    }
    export interface MultimediaEntity {
      url: string;
      caption: string;
      alt:string;
    }
    
    父组件

    import React, { FC, ReactElement, useEffect, useState } from "react";
    import Story from "./Story";
    
    const News: FC<NewsProps> = ({results:ResultsEntity}):ReactElement => {
      const [error, setError] = useState(null);
      const [stories, setStory] = useState<NewsProps>();
    
      useEffect(() => {
        const getCurrentPage = () => {
          const url = new URL(window.location.href);
          const page = url.pathname.split("/").pop();
          return page ? page : "home";
        };
    
        const section = getCurrentPage();
    
        fetch(
          `https://api.nytimes.com/svc/topstories/v2/${section}.json?api-key=4fzCTy6buRI5xtOkZzqo4FfEkzUVAJdr`
        )
          .then((res) => res.json())
          .then((data) => {
            setTimeout(() => setStory(data), 1500);
          })
          .catch((error) => {
            setError(error);
          });
      }, []);
    
      if (error) {
        return <div>Error: {error.message}</div>; // "Object is possibly 'null'"
      } else 
      if (!stories) {
        return <div>Loading...</div>
      } else {
        return (
          <>
            <ul className="stories">
              {stories.results.map((story, idx) => {  // "Object is possibly 'null' or 'undefined'"
                return (
                  <Story
                    key={idx}
                    title={story.title}
                    abstract={story.abstract}
                    img={story.multimedia[0].url}
                    alt={  // Type 'string | null' is not assignable to type 'string | undefined'. Type 'null' is not assignable to type 'string | undefined'.
                      story &&
                      story.multimedia &&
                      story.multimedia[0] &&
                      story.multimedia[0].caption
                        ? story.multimedia[0].caption
                        : null
                    }
                    link={story.url}
                  />
                );
              })}
            </ul>
          </>
        );
      }
    }
    export default News;
    

    child

    import React, { FC, ReactElement } from "react";
    
    interface StoryProps {
      title?: String;
      img?: string;
      alt?: string;
      abstract?: string;
      link?: string;
    }
    
    const Story: FC<StoryProps> = ({title, img, alt, abstract, link}): ReactElement => {
      return (
        <div className="story">
          <li className="story-title">{title}</li>
          <span className="story-content">
            <img className="story-img" src={img} alt={alt} />
            <span>
              <li className="story-body">{abstract}</li>
            </span>
          </span>
        </div>
      );
    };
    export default Story;
    

    最佳答案

    对于 error ,问题是当你创建状态时,你没有明确地给它一个类型,所以 typescript 必须尝试推断类型。它看到你传入了 null,所以它假设状态是(并且永远是)null :

    const [error, setError] = useState(null);
    
    如果您知道错误将是什么,您可以给出一个表示该错误的类型。例如:
    const [error, setError] = useState<null | { message: string }>(null);
    
    如果您什么都不知道,那么您可能需要求助于 any :
    const [error, setError] = useState<any>(null);
    

    对于 stories ,您已经定义了 .results属性可能为 null 或未定义:
    export interface NewsProps {
      results?: (ResultsEntity)[] | null;
    }
    
    ...但是您在使用它之前不会检查这些值。您需要编写代码来检查这些情况。例如,如果您只想跳过 map 语句并且不渲染任何内容,您可以这样做:
    {stories.results && stories.results.map((story, idx) => {
    
    或者与可选链接相同的东西(需要 typescript 3.7 或更高版本):
    {stories.results?.map(story, idx) => {
    

    对于alt Prop ,你传入null ,但这不是 alt 的合法值.传入undefined反而。
    alt={
      story &&
      story.multimedia &&
      story.multimedia[0] &&
      story.multimedia[0].caption
        ? story.multimedia[0].caption
        : undefined
    }
    
    或使用可选链接:
    alt={story?.multimedia?.[0]?.caption}
    

    关于reactjs - typescript / react : "Object is possibly ' null'",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66400875/

    相关文章:

    javascript - 性能问题: Components library following the dot notation structure

    javascript - 当从父级过滤时,React 子组件会取代另一个子级的状态

    javascript - 使用 node 和 sequelize 插入 postgress 数据库时出现无效的错误

    node.js - 使用 Node.js 和 TypeScript 的正确方法是什么?

    javascript - 使用 Resolve 查看之前在 Contentful 上托管的 Angular 8 加载图像

    json - 类没有实例 getter -JSON模型

    ios - 如何将 JSON 数据提取到 2 列中的原型(prototype)单元格

    reactjs - 要求至少将一个 prop 传递给组件 [typescript]

    ios - 如何在正确启动前从后台加载服务器数据

    javascript - 错误 : Cannot resolve module 'react-dom'