React,如何在 axios 请求的对象中对数组进行包含

Posted

技术标签:

【中文标题】React,如何在 axios 请求的对象中对数组进行包含【英文标题】:React, how to do an include on an array within an axios requested object 【发布时间】:2020-01-17 13:22:34 【问题描述】:

我正在做一个项目,我有一个可以有多个类别的项目。类别 ID 作为数组存储在项目对象中。我希望能够显示类别名称。

在下面的代码中,我尝试从后端获取类别(猫)。比使用带有包含参数的过滤器方法来检索所需的对象。

但是,在我尝试 this.state.prod.cat.includes(cats.id) 的行上,我收到“无法读取未定义的属性 'includes'”错误。

import React,  Component  from "react";
import axios from "axios";

import  Link  from "react-router-dom";

class items extends Component 
    state = 
        item: ,
        cats: []
    ;

    componentDidMount() 
        axios
            .get("http://localhost:5001/items/5d722a4e630c27623003dfcb")
            .then(response => 
                this.setState( item: response.data );
            )
            .catch(error => 
                console.log(error);
            );
    

    render() 
        axios
            .get("http://localhost:5001/cats")
            .then(response => 
                this.setState(
                    cats: response.data.filter(cats =>
                        this.state.item.cat.includes(cats.id)
                    )
                );
            )
            .catch(error => 
                console.log(error);
            );
        return (
            <div>
                this.state.cats.map(( _id, name ) => (
                    <Link exact to="/category/" + _id>
                        <span>name</span>
                    </Link>
                ))
            </div>
        );
    


export default items;

【问题讨论】:

嗨,肖恩,检查我的解决方案,如果有帮助,请告诉我。 【参考方案1】:

您收到错误是因为,组件首先呈现初始状态。最初你有item: ,所以当你做this.state.item.cat.includes(cats.id)时它会给你错误。

我认为你不应该在 render 方法中调用 API。

componentDidMount 是调用 API 的最佳位置。

您可以在 setState 中为您的 API 调用使用回调,

componentDidMount() 
  axios
    .get("http://localhost:5001/items/5d722a4e630c27623003dfcb")
    .then(response => 
        this.setState( 
           item: response.data 
        , () =>    //Call your API here
            axios
              .get("http://localhost:5001/cats")
              .then(response => 
                this.setState(
                  cats: response.data.filter(cats =>
                    this.state.item.cat.includes(cats.id)
                  )
                );
              )
              .catch(error => 
                console.log(error);
              );
        )
    )
    .catch(error => 
        console.log(error);
    );

【讨论】:

【参考方案2】:

使用 componentDidMount 调用您的 api。 componentDidMount 将在调用该渲染函数后从 api 获取数据。

import React,  Component  from "react";
import axios from "axios";

import  Link  from "react-router-dom";

class items extends Component 
    state = 
        item: ,
        cats: []
    ;

    componentDidMount() 
        axios
         .get("http://localhost:5001/items/5d722a4e630c27623003dfcb")
            .then(response => 
                this.setState( item: response.data );
            )
            .then(()=>
                   axios
            .get("http://localhost:5001/cats")
            .then(response => 
                this.setState(
                    cats: response.data.filter(cats =>
                        this.state.item.cat.includes(cats.id)
                    )
                );
            )
            )
            .catch(error => 
                console.log(error);
            );
    

    render() 
        return (
            <div>
                this.state.cats.map(( _id, name ) => (
                    <Link exact to="/category/" + _id>
                        <span>name</span>
                    </Link>
                ))
            </div>
        );
    


export default items;

【讨论】:

【参考方案3】:

强烈建议不要将 Render() 用于副作用(API 调用)。将代码移动到 ComponentdidMount。 每次状态更改时都会调用渲染函数,因此在 Render 中进行 API 调用绝对不是一个好主意。 提示:在功能组件中使用 useEffect 进行 API 调用。

这里是怎么做的

 componentDidMount() 
        axios.get('http://localhost:5001/cats')
  .then((res) => 
    // do something with cat Res

    return axios.get('http://localhost:5001/items/5d722a4e630c27623003dfcb');
  )
  .then((res) => 
    // do something with items res
  )
  .catch((err) => 
    // handle err
  );


另一种选择

 componentDidMount() 

  axios.all([
    axios.get('http://localhost:5001/cats'),
    axios.get('http://localhost:5001/items/5d722a4e630c27623003dfcb')
  ])
  .then(axios.spread((cats, items) => 
    // do something with both responses
  ));

    

【讨论】:

以上是关于React,如何在 axios 请求的对象中对数组进行包含的主要内容,如果未能解决你的问题,请参考以下文章

React js 和 axios POST 请求发送空数组

React - 多个 Axios 请求

如何在 React Native 中对数组进行分组

如何使用 react 访问 axios

使用 Axios 从 React 获取请求中的 Spring Pageable 对象

如何在 React 中对输入进行 base64 编码?