-1

im learning react where i was confused when i came across this

const index = countertemp.indexOf(counter);

React snippet below which works:-

state = {
    counters: [
      { id: 1, value: 0 },
      { id: 2, value: 0 },
      { id: 3, value: 2 },
      { id: 4, value: 11 }, 
    ],
  };

counter = { id: 3, value: 2 }

  handleIncrement = (counter) => {
    const countertemp = [...this.state.counters];
    console.log("handle increment counter temp vlaue => ", counter)
    const index = countertemp.indexOf(counter);  
    countertemp[index] = { ...counter };
    countertemp[index].value++;
    this.setState({ counters: countertemp });
  };

ES6 snippet:-

const counters= [
      { id: 1, value: 0 },
      { id: 2, value: 0 },
      { id: 3, value: 2 }, //2nd position
      { id: 4, value: 11 }, 
    ]
const counter={id: 3, value: 2}
const index = counters.indexOf(counter);  //it doesnt return 2
console.log(index)
> -1

There is related answer here regarding indexOf but its confusing why it works in react and not in es6 repl

update:- another approach

React:-

handleIncrement = (counter) => {
        const countertemp = [...this.state.counters];
        //const index = countertemp.indexOf(counter);
        const index = countertemp.map((x) => x.id).indexOf(counter.id)
    
        countertemp[index] = { ...counter };
    
        countertemp[index].value++;
        this.setState({ counters: countertemp });
      };

ES6:-
const counters= [
      { id: 1, value: 0 },
      { id: 2, value: 0 },
      { id: 3, value: 2 }, 
      { id: 4, value: 11 }, 
      { id: 11, value: 0 },
      { id: 23, value: 0 },
      { id: 43, value: 2 }, 
      { id: 453, value: 11 }, //7th
    ]
const counter={id: 453, value: 2}
const index = counters.map((x)=>x.id).indexOf(counter.id)
console.log(index)
> 7 
sherpaurgen
  • 3,028
  • 6
  • 32
  • 45
  • 2
    I'm surprised your code works in react - note that `counter` outside your callback function isn't used due to the argument counter inside your function. If you're wondering why it doesn't return 2 but -1 then your answer can be found [here](https://stackoverflow.com/questions/12604062/why-array-indexof-doesnt-find-identical-looking-objects). Can you create a [mre] of it working in React, preferably [using a code snippet](https://meta.stackoverflow.com/questions/338537/how-do-i-create-a-react-stack-snippet-with-jsx-support). – Nick Parsons Jul 28 '20 at 07:52
  • 1
    `indexOf` does a value comparison. For objects, that's their reference, so you'd only find the object in an array if you use the same object *from* the array, not an object that looks similar. – VLAZ Jul 28 '20 at 07:53
  • it should not work in React as well. The possible reason is redefined indexOf behavior. Are you sure it has not been extended by someone in your project? – Tarukami Jul 28 '20 at 08:05
  • @Nick Parsons here is link to the code https://github.com/sherpaurgen/videoly/blob/master/src/App.js – sherpaurgen Jul 28 '20 at 09:41
  • 1
    @satch_boogie Your `handleIncrement` method is being called by `() => this.props.onIncrement(this.props.counter)`, where `this.props.counter` is a reference to a counter object from your original array (you can see this in the Counters component as `counter` is being set to an object from your `counters` array in the `.map()` method). Using `.indexOf()` with the same object reference will work as expected, but using it with a different object won't work. So you can remove `counter = { id: 3, value: 2 }` and your code should still work fine. – Nick Parsons Jul 28 '20 at 09:50

2 Answers2

0

indexOf() compares searchElement to elements of the Array using strict equality (the same method used by the === or triple-equals operator).

Array.indexOf uses strict equality. So in your es6 example this equality check would fail.

console.log({ id: 3, value: 2 } === { id: 3, value: 2 })

Unfortunately your react example doesn't have enough information to say why (or why not) these objects would be strictly equal.

ksav
  • 20,015
  • 6
  • 46
  • 66
0

This would work

counters.indexOf(counters[2]); //returns 2

Because Array indexOf uses a === comparison.

Vasanth Gopal
  • 1,215
  • 10
  • 11