React - 我应该在哪个组件中执行http请求?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React - 我应该在哪个组件中执行http请求?相关的知识,希望对你有一定的参考价值。

在我的“Home.js”组件中,我想显示使用http请求(带有axios)获取的产品列表。我还有一个“Product.js”组件,我还需要以同样的方式获取产品。我不清楚在何处放置这种代码的准则。

如果我将这些请求放在他们各自的组件(Home和Product)中,那么他们必须是类组件吗?它们不能是无状态组件,因为产品数据需要存储在组件自身的状态中。我想,父App.js无法访问这些数据? (我不知道这是否重要)。

但是,如果我将所有这些东西放在父组件中,并将其传递给组件,它就会变得有点麻烦。我不想在所有页面上发出所有这些请求,因此我需要有条件地检查以查看当前的URL。我无法利用反应路由器的match.params获得“:产品”参数。我开始编写一些代码,我在App.js中发出请求,但它似乎不太顺利。我需要获取名为:product的参数,我想我可以通过使用更多正则表达式来解决它:

class App extends Component {

  state = {

    loading: false,
    product: [],
    products: []

  }

    componentWillMount() {

    const re = new RegExp('^/product');            

    if (window.location.pathname === '/' ){              // if url is '/', get products

            this.setState({loading: true})

            axios.get('/api/getproducts')
               .then(response => {

                this.setState({   
                    products: response.data,
                    loading: false
                })
            }))   
}
           // check if url begins with 'product', get product
else if  (re.test(window.location.pathname)){       

            // axios.get('/api/getproduct/' + match.params.product)   //need :product param
            // .then(response => {

        // })

    }

So, should I instead do data fetching in the components/routes where they need to be loaded, storing it in their own state?

我认为建议将所有数据放在顶层组件中。但在这种情况下,推荐的方式是什么?

答案

虽然这取决于你,但我认为只要它们是相关的,就可以更好地在更高阶的组件上发出请求。

所以在这种情况下,我会说你最好的选择是在你的Home组件而不是App中执行getproducts请求。这是因为App往往是构成整个应用程序的所有组件的起点(正如它的名字所暗示的那样)。对于小型应用程序而言,这可能没有什么区别,但是假设您正在使用数十个组件制作更大的组件,每个组件都有自己的必要请求。如果所有这些都在App组件中,那将是完全混乱。

更不用说,如果您在应该在某个URL中呈现的组件中,您不必担心检查它。如果安装了相关组件,则会发出请求。

现在对于第二部分,在产品组件中制作getproduct请求似乎更有意义。由于它可能会获取与产品相关的数据,这是正确的吗?

所以,无论如何,鉴于帖子中提到的信息,我建议像这样:

对于Home.js文件:

export default class Home extends React.Component {
  constructor (props) {
    super(props)

    this.state = {
      loading: true,
      products: []
    }
  }

  componentWillMount () {
    axios.get('/api/getproducts')
    .then(response => {

      this.setState({   
          products: response.data,
          loading: false
      })
    })
  }

  render () {
    const { loading, products } = this.state
    if (loading) {
      return (
        <div>Loading...</div>
      )
    }

    // Note: I am using product.id and product.name, but it really is whatever you are using to identify your different products
    // I have also made it in a way that will link to the product
    return (
      <ul>
        products.map(product =>
          <li>
            <Link to=`/${product.id}`>
               product.name
            </Link>
          </li>
        )
      </ul>
    )
  }
}

对于Product.js文件:

export default class Product extends React.Component {
  constructor (props) {
    super(props)

    this.state = {
      loading: true,
      product: []
    }
  }

  componentWillMount () {
    axios.get(`/api/getproduct/${this.props.match.params.product}`)
    .then(response => {

      this.setState({   
          product: response.data,
          loading: false
      })
    })
  }

  render () {
    const { loading, product } = this.state
    if (loading) {
      return (
        <div>Loading...</div>
      )
    }

    return (
     <div>
     {product.whatever}
     </div>
    )
  }
}

以上是关于React - 我应该在哪个组件中执行http请求?的主要内容,如果未能解决你的问题,请参考以下文章

我应该在 redux-react 应用程序的哪个位置包含有状态的展示组件?在组件或容器文件夹中?

[react] react中发起网络请求应该在哪个生命周期中进行?为什么?

从http请求中 获得请求参数 应该调用哪个方法

HttpServlet的子类要从HTTP请求中获得请求参数,应该调用哪个方法?

在 React 中,如何在所有组件中拥有一个自定义钩子实例?

角度 4:从不同的组件调用方法