W
W
WarriorKodeK2018-06-06 10:47:20
React
WarriorKodeK, 2018-06-06 10:47:20

Why is console.log called twice?

Good morning. I have an action to get information from the back.

Action
import ProductsService from "../../config/productService";
import {
  FETCHING_PRODUCT_DETAIL,
  FETCHED_PRODUCT_DETAIL
} from "../../config/constants";

const fetchingProductDetail = payload => {
  return {
    type: FETCHING_PRODUCT_DETAIL,
    payload
  };
};

const fetchedProductDetail = payload => {
  return {
    type: FETCHED_PRODUCT_DETAIL,
    payload
  };
};

export const getProductDetail = id => dispatch => {
  dispatch(fetchingProductDetail(id));

  ProductsService.getProductById(id).then(data =>
    dispatch(fetchedProductDetail(data))
  );
};

A reducer has been created for it. In the reducer, when the data is just starting to load into the state, I add loading: trueand when the data has loaded loading: false.
reducer
import {
  FETCHING_PRODUCT_DETAIL,
  FETCHED_PRODUCT_DETAIL
} from "../../config/constants";

const initialState = {
  loading: false,
  productDetail: {},
  productDetailData: [],
  error: null
};

export const productDetail = (state = initialState, action) => {
  switch (action.type) {
    case FETCHING_PRODUCT_DETAIL:
      return {
        ...state,
        loading: true
      };
    case FETCHED_PRODUCT_DETAIL:
      return {
        ...state,
        loading: false,
        productDetail: action.payload.product,
        productDetailData: action.payload.data
      };
    default:
      return state;
  }
};

And in the component, when the data has loaded ( loading: false) I call console.log("DATA LOADED"). But for some reason it is called 2 times, and at the first call, the data has not yet arrived (an empty array), and the second time all the data has arrived.
Component
import React, { Component } from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import ProductService from "../../config/productService";
import { getProductDetail } from "../../actions/productDetail/productDetail";

import { Button, Row, Col, Container } from "reactstrap";

import ModalComponent from "../../components/common/Modal/Modal";
import TableComponent from "../../components/Table/TableComponent";
import ProductDetail from "../../components/ProductDetail/ProductDetail";

class ProductDetailContainer extends Component {
  state = {
    showModal: false
    // tableData: [{name: 'Americano', maxPrice: 11, minPrice: 12, averagePrice: 111, soldOut: 10.000}]
  };

  toggleModal = () => {
    this.setState({
      showModal: !this.state.showModal
    });
  };

  componentDidMount() {
    const {
      match: {
        params: { id }
      },
      getProductDetail
    } = this.props;
    getProductDetail(id);
  }

  createTableData = arr => {
    return arr.map((element, index) => {
      return {
        name: element.banner.name,
        maxPrice: ProductService.maxPrice(element.pricingDataByWeek),
        minPrice: ProductService.minPrice(element.pricingDataByWeek),
        averagePrice: ProductService.averagePrice(element.pricingDataByWeek),
        soldOut: "10.000"
      };
    });
  };

  render() {
    const { productDetail, productDetailData, loading } = this.props;
    const { showModal, data } = this.state;
    return (
      <Container>
        <ProductDetail data={productDetail} />
        <Row>
          <Col sm={{ offset: 9 }}>
            <Button color="primary" onClick={this.toggleModal}>
              Hello
            </Button>
          </Col>
          <Col>
            <Button color="primary">Create Report</Button>
          </Col>
          <ModalComponent showModal={showModal} toggle={this.toggleModal} />
        </Row>
        {loading
          ? console.log(`DATA NOT LOADED ${JSON.stringify(productDetailData)}`)
          : console.log(`DATA LOADED ${JSON.stringify(productDetailData)}`)};
      </Container>
    );
  }
}

const mapStateToProps = state => {
  return {
    ...state.productDetail
  };
};

const mapDispatchToProps = {
  getProductDetail
};

ProductDetailContainer.propTypes = {
  productDetail: PropTypes.object.isRequired,
  getProductDetail: PropTypes.func.isRequired,
  productDetailData: PropTypes.array.isRequired
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(ProductDetailContainer);
5b17914a34196864245007.pngQ - How can I skip this first empty array load and why is it rendering?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Anton Spirin, 2018-06-06
@WarriorKodeK

The componentDidMount method is called after render . Apparently, the first time you call render , you have the productDetail.loading property set to false .
If you are going to render a list, then there is nothing to worry about, since there will be no error with an empty [].map array, and after render , loading will start immediately.
In other cases, additional checks must be made.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question