0

I have done an array.map() that loop through json file (goods.json). Then I want to make some manipulations with it (want to delete item from this array in removeCard(obj) method for example). Render is ok but the problem is that I don't understand why I can't see shoppingCardsJSX array in removeCard(obj) method, always get underfined. I have read answers in How to delete a ToDo Item onClick in React? and Remove item from array in React but unfortunately I didn't understand how it works. Can you please help me find out what I'm doing wrong ? Hope this part of code can illustrate my problem,

import { sample } from 'rxjs/internal/operators';
import React from 'react';
import ShoppingCard from './ShoppingCard';
import goods from './goods.json';

export default class ShoppingCards extends React.Component {
    constructor (props){
        super(props);
    }
    removeCard(obj){
        console.log("fireeeee");
        console.log(obj);
        console.log(this.shoppingCardsJSX);
    }
    render() {
        console.log("render");
        let shoppingCardsJSX = goods.map((good) => {
            return (
                <ShoppingCard
                    key = {good.id }
                    goodId = {good.id}
                    src = {good.src}
                    price = {good.price}
                    onRemoveCard={this.removeCard}
                />
            );
        });
        console.log(shoppingCardsJSX);
        return shoppingCardsJSX;
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
prostyash
  • 117
  • 1
  • 13

4 Answers4

1

It looks like you never set this.shoppingCardsJSX and also you also should use this.removeCard.bind(this) instead of this.removeCard as a prop, because then it can reference this when it is called.

import { sample } from 'rxjs/internal/operators';
import React from 'react';
import ShoppingCard from './ShoppingCard';
import goods from './goods.json';

export default class ShoppingCards extends React.Component {
    constructor (props){
        super(props);
    }
    removeCard(obj){
        console.log("fireeeee");
        console.log(obj);
        console.log(this.shoppingCardsJSX);
    }
    render() {
        console.log("render");
        this.shoppingCardsJSX = goods.map((good) => {
            return (
                <ShoppingCard
                    key = {good.id }
                    goodId = {good.id}
                    src = {good.src}
                    price = {good.price}
                    onRemoveCard={this.removeCard.bind(this)}
                />
            );
        });
        console.log(this.shoppingCardsJSX);
        return this.shoppingCardsJSX;
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
Asleepace
  • 3,466
  • 2
  • 23
  • 36
1

It looks like running the code snippet is returning an error because you're never actually setting shoppingCardsJSX to the component. Your console.log(this.shoppingCardsJSX); statement is causing it to error out

You can always try wrapping it in a div:

import { sample } from 'rxjs/internal/operators';
import React from 'react';
import ShoppingCard from './ShoppingCard';
import goods from './goods.json';

export default class ShoppingCards extends React.Component {
    constructor (props){
        super(props);
    }
    removeCard(obj){
        console.log("fireeeee");
        console.log(obj);
    }
    render() {
        return (
           <div>
             {
              goods && goods.map((good) => {
                return (
                  <ShoppingCard
                    key = {good.id }
                    goodId = {good.id}
                    src = {good.src}
                    price = {good.price}
                    onRemoveCard={this.removeCard}
                  />
                );
              });
            }
        </div>
      )
    }
}
Ariel Salem
  • 357
  • 3
  • 12
0

You should use an arrow function to bind the this keyword to removeCard function like this

removeCard = (obj) => {
        console.log("fireeeee");
        console.log(obj);
        console.log(this.shoppingCardsJSX);
    }

The other way is to do this

<ShoppingCard
    key = {good.id }
    goodId = {good.id}
    src = {good.src}
    price = {good.price}
    onRemoveCard={this.removeCard.bind(this}
/>

However don't mix the two.

Joseph Akayesi
  • 461
  • 1
  • 10
  • 31
0

Use Arrow function as they are binded by default. you dont need to bind these arrow functions.

 removeCard=(obj)=>{
        console.log("fireeeee");
        console.log(obj);
        console.log(this.shoppingCardsJSX);
    }