尽管直接在该组件中获取状态,但Redux状态仍未传递给嵌套路由器组件

时间:2019-07-23 16:22:33

标签: reactjs redux react-redux react-router

我有一个react-redux状态,它是从后端数据库中提取的“产品”对象的数组。我有一个“ ProductList”组件,用于接收提取的对象并创建产品列表。我直接在此“ ProductList”组件中调用“ fetchProducts()”方法。该“ ProductList”组件可以刷新,并且每次刷新后,提取的产品将保留并重新出现。

但是,我在嵌套的路由器路由中有另一个“ ViewProduct”组件,在该路由中,我也正在提取相同的“ products”数组。问题在于该组件中,刷新时,尽管我也直接在组件内部调用“ fetchProducts()”,但“产品”状态不会持久并返回未定义状态。

我将products数组直接传递到“ ProductView”组件中,但它并没有像我的“ ProductsList”组件一样持续刷新。

这是我的“ AllProductsList”组件,该组件在刷新时成功保存产品数据。它位于路线“ / products / all”中:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { fetchProducts } from '../actions/productAction.js';
import ProductCard from '../components/ProductCard.js';

class AllProductsList extends Component {

  componentDidMount() {
    this.props.fetchProducts()
  }

  renderDiv = () => {
    return this.props.products.map((product) =>
      <ProductCard key={product.id} product={product} />
    )
  }

  render() {
    return(
      <div>
        {this.renderDiv()}
      </div>
    )
  }
}

AllProductsList.propTypes = {
  fetchProducts: PropTypes.func.isRequired,
  products: PropTypes.array.isRequired,
}

const mapStateToProps = state => ({
  products: state.products.items,
})

export default connect(mapStateToProps, { fetchProducts })(AllProductsList)

这是问题“ ProductView”组件,在刷新后不保留产品数据。该组件位于路线/ product /:id上:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { fetchProducts } from '../actions/productAction.js';

class ProductView extends Component {

  constructor(props) {
    super(props)
    this.state = {
      buttonMessage: 'Add to cart',
      quantity: 0,
    }
  }

  componentDidMount() {
    this.props.fetchProducts()
  }

  quantityChangeReader = (e) => {
    this.setState({ quantity: e.target.value })
  }

  render() {
    return(
      <div>
        <ul>   
<li>this.props.products[this.props.match.params.productId].name</li>
<li>this.props.products[this.props.match.params.productId].comments</li>
<li>this.props.products[this.props.match.params.productId].photos[1].url</li>
        </ul>
      </div>
    )
  }
}

ProductView.propTypes = {
  fetchProducts: PropTypes.func.isRequired,
  products: PropTypes.array.isRequired,
}

const mapStateToProps = state => ({
  products: state.products.items,
})

export default connect(mapStateToProps, { fetchProducts })(ProductView)

“ ProductView”的父组件,该组件在App.js中被路由到:

import React from 'react';
import ProductView from '../components/ProductView.js';
import { Route } from 'react-router-dom';

const ProductViewContainer = ({ match, products }) => (

      <div>
        <Route path={`${match.url}/:productId`} render={routerProps => <ProductView {...routerProps} /> }/>
      </div>
)

export default ProductViewContainer

在第二种情况下,对于组件ProductView,刷新时将返回错误消息“无法读取未定义的.name”。然而,在第一个组件(“ AllProductsList”)中,刷新将再次成功返回数组。

根据要求,这是路由器:

      <Provider store={store}>
        <Router>
          <NavBar />
          <Route exact path="/" component={Carousel} />
          <Route exact path="/about" component={OurStory} />
          <Route exact path="/products/necklaces" component={NecklacesList} />
          <Route exact path="/products/bracelets" component={BraceletsList} />
          <Route exact path="/products/earrings" component={EarringsList} />
          <Route exact path="/products/all" component={AllProductsList} />
          <Route exact path="/events" component={Events} />
          <Route exact path="/cart" component={Cart} />
          <Route path='/product' render={routerProps => <ProductViewContainer {...routerProps} />} />
          <Credits />
        </Router>
      </Provider>

2 个答案:

答案 0 :(得分:0)

ProductView组件中,当组件首次渲染时,this.props.products将是undefined。这将在页面刷新时发生,或者在浏览器中直接点击产品ID路由时发生,这两种情况都会重置您的redux状态。

要抑制此情况,您需要在组件中添加一个检查以确认是否已填充products道具。

喜欢这个...

render() {
  const { products } = this.props;
  if (products.length) {
    // render the rest of your view
  } else {
    // products is still fetching...
  }
}

答案 1 :(得分:0)

刷新页面时,React-redux不会保留数据。如果要保留数据,请存储在本地存储中。 刷新页面时,最初的this.props.products为空。一旦获取数据,this.props.products将具有远程数据,并且组件将重新呈现。您可以将if条件放在ProductView组件中