【问题标题】:mapStateToProps state returns 'undefined' two times before fetching the data from firebase在从 firebase 获取数据之前,mapStateToProps 状态两次返回“未定义”
【发布时间】:2019-09-09 03:16:00
【问题描述】:

组件在挂载之前不会从 Firebase 检索数据。

const mapStateToProps = (state, ownProps) => {
  return {
    products: state.firestore.ordered.products
  };
};

当我在安装后测试道具时......

componentDidMount() {
    console.log(this.props);
}

this.props.product 的值未定义。


如果我 console.log 在 mapStateToProps() 中的 state 参数,我会立即得到两个未定义的 console.logs,不久之后,我会收到我想要的实际数组。

const mapStateToProps = (state, ownProps) => {
  const products2 = state.firestore.ordered.products;

  console.log(products2);  //returns 2 console logs of undefined,
  // after a second (after the component mounts) it gives me the data

  return {
    products: state.firestore.ordered.products
  };
};

这是一个问题的原因是当我想使用来自 Firebase 的数据来呈现组件时。

<div className="item-render-space">
          {products
            .filter(
              eachProduct =>
                eachProduct.landingPageCategory.indexOf(this.props.category) >
                -1
            )
            .map(eachProduct => (
              <div className="each-product" key={eachProduct.id}>
                <Link to={"/product/" + eachProduct.id}>
                  <img src={eachProduct.image} alt="#" />
                  <p className="product-price">{eachProduct.price}</p>
                  <p className="product-name">
                    {nameShortener(eachProduct.name)}
                  </p>
                </Link>
              </div>
            ))}
        </div>

我收到一个错误屏幕,因为变量“products”未定义,因为来自 firebase 的数据在开始渲染时尚未到达组件。

如何解决这个问题?!

编辑:这是 rootReducer:

const rootReducer = combineReducers({
  firestore: firestoreReducer, //connects to firestore
  live: liveReducer, //used locally for opening bootstrap modals
  products: productsReducer, //previous products store before implementing Firestore
  firebase: firebaseReducer //connects to firebase
});

【问题讨论】:

  • 条件渲染(this.props.products && this.props.products.length > 0)或默认为空数组[]。这不是 react-redux 或 firebase 独有的,这是异步检索数据的常见问题。
  • 如何默认为空数组?
  • 你通常如何在 your redux store 中默认一个值?您也可以考虑defaultProps 或简单地在mapStateToProps() 甚至render() 中使用诸如|| 之类的逻辑运算符。有很多方法,这取决于您的应用程序。分享你的 reducer 或许可以获取更多关于你的 store 结构的信息。
  • 我对 redux 和 firebase 还很陌生,我需要在组件中创建一个 reparate 函数吗?我尝试这样做,但失败了。我尝试创建一个 if(product !== undefined) 但我没有尝试过。我将分享减速器 1 秒
  • 请分享您的减速器以及您的initialState 的外观以获得更多帮助。至少尝试以下{products &amp;&amp; products.length &gt; 0 &amp;&amp;。另请查看以下reactjs.org/docs/conditional-rendering.html

标签: reactjs firebase redux react-redux google-cloud-firestore


【解决方案1】:

尝试使用conditional rendering 以避免尝试在undefined 上执行 Array.prototype.filter() 和 Array.prototype.map()。以下将检查 products 是否真实,并且 length 是否大于 0:

<div className="item-render-space">
  {products && products.length > 0 && products
    .filter(
      eachProduct =>
        eachProduct.landingPageCategory.indexOf(this.props.category) >
        -1
    )
    .map(eachProduct => (
      <div className="each-product" key={eachProduct.id}>
        <Link to={"/product/" + eachProduct.id}>
          <img src={eachProduct.image} alt="#" />
          <p className="product-price">{eachProduct.price}</p>
          <p className="product-name">
            {nameShortener(eachProduct.name)}
          </p>
        </Link>
      </div>
    ))}
</div>

希望对您有所帮助!

【讨论】:

    猜你喜欢
    • 2017-05-31
    • 2019-11-10
    • 1970-01-01
    • 1970-01-01
    • 2020-11-15
    • 1970-01-01
    • 2018-07-16
    • 1970-01-01
    • 2016-12-22
    相关资源
    最近更新 更多