简体   繁体   中英

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.

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

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

  1. 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
  2. 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

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

  1. 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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM