0

I have code

import React,{Component} from "react"
import {connect} from "react-redux"
class Aside extends Component{
  renderAside(){
    const asideItems = this.props.cart
    console.log(asideItems) // Not Working never
    return asideItems.map((item, key) =>{
      return(
        <div className="aside-item" key={key}>
          <div className="aside-item__name">{item.product.name}</div>
        </div>
      )
    })
  }

  render(){
    return (
      <div>
        {this.renderAside()} 
      </div>
    )
  }

}



const mapStateToProps = (state) => {
  console.log(state.asideReducer.cart) // Working when updated cart
  return{
    cart: state.asideReducer.cart
  }
}

export default connect(mapStateToProps)(Aside)
  

How make when i updated state.asideReducer.cart update my render? For example, I click on other elements and in my state cart push new elements. And when my cart update I need to update my aside( for display products in the cart ) Thanks very much

MRazaImtiaz
  • 1,964
  • 1
  • 13
  • 23
Dan
  • 179
  • 10

3 Answers3

1

Since you don't have much functionality taking place in either of these components, then I would suggest mapping in-line rather than utilizing an additional function (renderAside) for this process. You don't either have anything that requires a stateful/class component, so I would suggest changing this to a functional component to avoid needing a constructor. If you need state later, just use hooks.

Another thing to note is that with ES6, you should be using arrow functions.

renderAside(){ /// change this function to an arrow function
renderAside = () => { /// should be
import React from 'react';
import { connect } from 'react-redux';

const Aside = (props) => {
  let { cart } = props;
  console.log(cart);

  return (
    <div>
      {cart.map((item, key) => {
        return (
          <div className="aside-item" key={key}>
            <div className="aside-item__name">{item.product.name}</div>
          </div>
        );
      })}
    </div>
  );
};

const mapStateToProps = (state) => {
  return {
    cart: state.asideReducer.cart,
  };
};

export default connect(mapStateToProps)(Aside);

In the future.... If you're trying to dynamically update the DOM with new elements then you'd need to invoke your mapping function. You're calling it when the page is first rendered. The DOM isn't going to update just because something new is added. You have to re-render that data. In a stateful component you would update the state variable then invoke your mapping function each time that state has been successfully updated.

Mario Petrovic
  • 7,500
  • 14
  • 42
  • 62
Kota
  • 157
  • 7
  • console.log(cart) . Working only once, when start page. I have Redux DevTools, and i see, asideReducer cart update, and workng correct, but render not update. Render not following update store to cart – Dan Dec 14 '20 at 06:55
  • console.log(cart) will only work on render the first time in this use-case. To view the logs each time you would need to move the console.log() into your mapper function just before return in the DOM. In terms of the mapping issue, remove key from the parameters of the mapping function. Then instead of key={key} you would use key={item.product.id} assuming that there is a product id. This acts as a GUID-like identifier in that once the key changes the DOM should update. – Kota Dec 14 '20 at 07:25
  • Mapper function working only if in initialState I put some products. For example const initialState = { cart: [ {product:{name: "Test"} , quantity: 2}, {product:{name: "Test2"} , quantity: 3}, {product:{name: "Test3"} , quantity: 42}, {product:{name: "Test4"} , quantity: 5}, ] } And mapper function working. Later, if i add in state new products( and i see what state update) mapper function not working, i.e render to element run once, when component render first time – Dan Dec 14 '20 at 07:32
  • Are you using a in your App? https://stackoverflow.com/questions/58249720/how-to-update-react-component-after-changing-state-through-redux – Kota Dec 14 '20 at 07:48
0

You should bind your renderAside when using function declaration

  1. First way - bind your function before using

    class Aside extends Component {
       constructor(props) {
         super(props);
    
         // This binding is necessary to make `this` work in the callback
         this.renderAside = this.renderAside.bind(this);
       }
    
       // ...
     }
    
  2. Two way - using arrow function

     renderAside = () => { // Change this line
         const asideItems = this.props.cart
         console.log(asideItems) // Not Working never
         return asideItems.map((item, key) =>{
           return(
             <div className="aside-item" key={key}>
               <div className="aside-item__name">{item.product.name}</div>
             </div>
           )
         })
       }
    
Hải Bùi
  • 2,492
  • 2
  • 9
  • 17
  • I try both options, buy it's not worked. I noticed if initialState is not empty, component rendering, i.e component not following changes in redux. But why? – Dan Dec 14 '20 at 06:50
0

I'm not correct return my new state

Incorrect

return {
        ...state, cart: cart
      }

Correct code

 return {
        ...state,
        cart: [...state.cart, action.payload]
      }
Dan
  • 179
  • 10