hypermode
hypermode

Reputation: 23

React - Trying to reference this.props inside reduce()-function

I have little experience with JS and I'm following a video course on React. Most things makes sense but I'm having some trouble with reference scopes.

Here's what the tutor writes:

const orderIds = Object.keys(this.props.order);

const total = orderIds.reduce((prevTotal, key) => {
  const fish = this.props.fishes[key];
  const count = this.props.order[key];
  const isAvailable = fish && fish.status === 'available';
  if (isAvailable === true) {
    return prevTotal + count * fish.price;
  } else {
    return prevTotal;
  }
}, 0);

He is using an arrow-function. It works of course.

I want to do the same but with writing a "normal" function, because for now I don't want to make any shortcuts:

const orderIds = Object.keys(this.props.order);

const total = orderIds.reduce(
  function(prevTotal, key) {

    const fish = this.props.fishes[key];
    const count = this.props.order[key];
    const isAvailable = fish && fish.status === 'available';

    if (isAvailable === true) {

      return prevTotal + (count * fish.price);

    } else {

      return prevTotal;

    }

  }
, 0);

The problem is:

TypeError: this is undefined

So there's a problem with the scope of the reference to this.props...

I got this to work within a .map()-function by passing it a second argument of

... , this)

from searching online about referencing this.

That doesn't work for the reduce()-function. So, what can one do in my situation? Again, I don't want to use the shorter arrow-function because it's like a shortcut I don't want to use when learning. I've searched online about scopes on this and also about the reduce()-function but the examples I've seen doesn't quite fit what I'm looking for, or I'm simply not savvy enough to use what they're writing.

Thanks a ton if you can help me out, regards / HW

Upvotes: 2

Views: 189

Answers (2)

Denis Tambovchanin
Denis Tambovchanin

Reputation: 556

You can use bind as suggest upper or rewrite code like this:

const orderIds = Object.keys(this.props.order);
const { fishes, order } = this.props;

const total = orderIds.reduce(
  function(total, key) {
    const fish = fishes[key];
    const count = order[key];
    const isAvailable = fish && fish.status === 'available';

    if (!isAvailable) return total;

    return total + (count * fish.price);
  }
, 0);

Upvotes: 0

Zohaib Ijaz
Zohaib Ijaz

Reputation: 22885

Arrow functions has parent scope so this represents parent's this but simple function don't. You can tell the function about this using .bind(this)

const total = orderIds.reduce(
  (function(prevTotal, key) {
    const fish = this.props.fishes[key];
    const count = this.props.order[key];
    const isAvailable = fish && fish.status === 'available';
    if (isAvailable === true) {
      return prevTotal + (count * fish.price);
    } else {
      return prevTotal;
    }

  }).bind(this)
, 0);

Upvotes: 1

Related Questions