首页 > 解决方案 > 在从 firebase 获取数据之前,mapStateToProps 状态两次返回“未定义”

问题描述

组件在挂载之前不会从 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
});

标签: reactjsfirebasereduxreact-reduxgoogle-cloud-firestore

解决方案


尝试使用条件渲染来避免尝试执行 Array.prototype.filter() 和 Array.prototype.map() undefined。以下将检查是否products真实且 alength大于 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>

希望这会有所帮助!


推荐阅读