在我的" Home.js
"组件我想显示使用http请求(使用axios)获取的产品列表。我还有一个" Product.js
"组件,我还需要以相同的方式获取产品。我不清楚有关放置此类代码的指南。
如果我将这些请求放在各自的组件(Home和Product)中,那么它们必须是类组件吗?它们不能成为无状态组件,因为产品数据需要存储在组件自身状态中。那个数据无法被父App.js访问,我想? (我不知道这是否重要)。
但是,如果我将所有这些东西放在父组件中,并将其传递给组件,它就会变得有点麻烦。我不想在所有页面上发出所有这些请求,因此我需要有条件地检查以查看当前网址。我无法利用match.params
反应路由器来获得"产品" PARAM。我开始使用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?
我认为建议将所有数据放在顶层组件中。但在这种情况下,推荐的方式是什么?
答案 0 :(得分:2)
虽然由您自己决定,但我认为只要它们是相关的,就可以更好地对更高阶的组件发出请求。
所以在这种情况下,我会说你最好的选择是在你的Home组件而不是App中执行getproducts
请求。这是因为App往往是构成整个应用程序的所有组件的起点(正如它的名字所暗示的那样)。对于小型应用程序而言,这可能没有什么区别,但是假设您正在使用数十个组件制作更大的组件,每个组件都有自己的必要请求。如果所有这些都在App组件中,那将是完全混乱。
更不用说,如果您在应该在某个URL中呈现的组件中,您不必担心检查它。如果安装了相关组件,则会发出请求。
现在对于第二部分,使getproduct
请求似乎在Product组件中更有意义。由于它可能会获取与产品相关的数据,这是正确的吗?
所以,无论如何,鉴于帖子中提到的信息,我建议像这样:
对于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>
)
}
}