Stack Exchange
Increase number by click in react.js
I'm writing a Product component in react.js, and I'd like to increase the inCartCount value of actual product when the item is clicked.
import React, { PropTypes } from 'react';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import s from './Product.css';

var NumberFormat = require('react-number-format');
class Product extends React.Component {

    addToCart(product) {
        console.log(product.inCartCount);
        product.inCartCount++;
    }

    render() {

        const product = this.props.data;

        product.inCartCount = product.inCartCount || 0;

        return (
            <div onClick={this.addToCart.bind(this, product)}>
                <h3>{product.name}</h3>
                <NumberFormat value={product.price} displayType={'text'} thousandSeparator={true} suffix={' Ft'}/>
                <span>{product.inCartCount}</span>
            </div>
        );
    }
}

export default withStyles(s)(Product);

in console.log the value is increasing, but it is not rendered to DOM, I always see 0 as inCartCount value in the browser.

Problem is you are reinitialising the product in render every time, possible solutions:

Update the parent component with new count, pass a function from parent to child.

In Parent Component:
<Product
    updateProduct={this.updateProduct.bind(this)}
    data={this.state.data}    
/>

updateProduct(value){
    this.setState({data:value});
}

In Child Component:
addToCart(product) {
    console.log(product.inCartCount);
    product.inCartCount++;
    this.props.updateProduct(product);
}

2. Store the product in state on child component like this:
import React, { PropTypes } from 'react';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import s from './Product.css';

var NumberFormat = require('react-number-format');

class Product extends React.Component {
     constructor(props) {
       super(props);
       this.state = {
         product: props.data
       };
     }  

    addToCart() {
       let product = this.state.product;
       product.inCartCount = product.inCartCount ? product.inCartCount+1 : 1;
       this.setState({product});
    } 

    render() {
       return (
          <div onClick={this.addToCart.bind(this)}>
              <h3>{this.state.product.name}</h3>
              <NumberFormat value={this.state.product.price} displayType={'text'} thousandSeparator={true} suffix={' Ft'}/>
              <span>{this.state.product.inCartCount}</span>
          </div>
       );
    }
}

export default withStyles(s)(Product);


updating count in child like this product.inCartCount++; is not correct this should be moved to parent product should be immutable and not update-able

i dont know his product structure, i just told him all the possible ways of solving the issue he is facing. if he just want the data in child component then no need to pass it to parent again.

You can't use code like you do it. To increment the counter you should use this.state.counter and use this variable into you component. Because every time when your this.state changed, your component automatically re-rendering and take new this.state. If you just change the value manually how you did this - components isn't re-rendering and you never see the changed value at the page.
But don't forget to initalizing the this.state = {counter: 0}; at first in the method getInitialState() Like this:
  getInitialState() {
    return { counter: 0 };
  }

and use it into render method or into any methods like this.state.counter

he is using es6, getInitialState() will not work, he have to use constructor.

You fetch the product each time from the props which is immutable and will never be updated, you have 2 options here:

Update parent with the new count and set its state to update product and that will re-render child with new product props and have a new count
Initialize state with the props from parent and then you are controlling the state for product and in this case you will need to set the state to new product after updating the count to re-render  

