【问题标题】:Why isn't this React iteration of images working?为什么这个图像的 React 迭代不起作用?
【发布时间】:2021-10-03 13:00:57
【问题描述】:

我正在学习 React 并调用 Dog API。我让它用于渲染图像,但是当我尝试渲染多个图像时,它不起作用。对于上下文,API 调用链接是https://dog.ceo/api/breeds/image/random/5,其中“/5”指定图像的数量。我很确定正在设置状态,因为当我放置 console.log 而不是设置状态时,它给了我带有图像 URL 的 JSON。我收到一条错误消息“无法读取未定义的属性 'map'”。

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [],
    }
  }

  componentDidMount() {
    fetch("https://dog.ceo/api/breeds/image/random/5")
      .then(response => response.json())
      .then(json => this.setState({data: json}));
  }
  
  render() {
    return (
      <div>
        {this.state.data.message.map((item, id) => (
          <img src={item} key={id} alt="dog" />
        ))}
      </div>
    )
  }
}

export default App;

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    this.state.data.message 在组件首次加载时不存在。相反,您已将 this.state.data 设置为一个空数组,然后将其替换为一个对象。最好保持类型一致。

    最简单的更改可能只是将this.state.data.message设置为一个空数组:

    constructor(props) {
      super(props);
      this.state = {
        data: {
          message: []
        },
      }
    }
    

    从那里开始,注意到 AJAX 操作的异步特性,您还可以考虑在没有要显示的图像时实现“加载状态”。 (当操作完成并且仍然没有图像时,甚至可能是有意义的空状态?错误状态?等等)

    【讨论】:

      【解决方案2】:

      检查数据是否被操纵。如果尚未通过 API 调用设置状态,则没有任何内容 this.state.data.message

      请注意?. 符号称为Optional Chaining。可选链接用于检查对象是否在深层中具有密钥,并且可选链接不支持IE

      render() {
          return (
              <div>
                  {this.state.data?.message?.length > 0 && this.state.data.message.map((item, id) => (
                      <img src={item} key={id} alt="dog" />
                  ))}
              </div>
          );
      }
      

      【讨论】:

      • 只有当 OP 使用 typescript 时才有效,不会出现
      • 为什么它只适用于打字稿?
      • 感谢您提供有关可选链接的信息。现在我收到一条错误消息,上面写着“this.state.data.message.map 不是函数”,是我做错了什么吗?
      • 我已经检查过了,它正在工作。你写的 render 函数和我写的完全一样吗?
      • 哦,是的,它有效。出于某种原因,我从 API 调用中取出了“/5”,然后将其重新添加进去,它就可以工作了。谢谢。
      【解决方案3】:

      这是因为当页面最初呈现时,data 状态只是一个空数组。您必须将? 添加为optional chaining,当您访问未定义的属性时,这基本上会“忽略”错误。

      你的代码应该是这样的

      render() {
          return (
            <div>
              {this.state.data.message?.map((item, id) => (
                <img src={item} key={id} alt="dog" />
              ))}
            </div>
          )
        }
      

      所以当data 状态为空时,它不会渲染任何东西。 另一种方法是检查状态是否有内容

      render() {
          return (
            <div>
              {this.state.data.message &&
               this.state.data.map((item, id) => (
                <img src={item} key={id} alt="dog" />
              ))}
            </div>
          )
      

      此代码将检查data.message 是否为真并渲染组件,否则将不渲染任何内容。更多信息here }

      【讨论】:

        猜你喜欢
        • 2010-10-20
        • 1970-01-01
        • 1970-01-01
        • 2011-05-22
        • 2021-07-19
        • 1970-01-01
        • 1970-01-01
        • 2010-11-11
        • 2023-03-23
        相关资源
        最近更新 更多