Skip to content
Advertisement

Why is this onClick event handler firing twice in my create-react-app

can someone tell me why is this “upvote” onClick handler firing twice? the logs would indicate it’s only running once but the score it controls increases by 2

export default class Container extends Component {
  constructor(props) {
    super(props);

    this.state = {
      jokes: [],
    };
    this.getNewJokes = this.getNewJokes.bind(this);
    this.retrieveJokes = this.retrieveJokes.bind(this);
    this.upVote = this.upVote.bind(this);
  }
upVote(id) {
    this.setState(state => {
      //find the joke with the matching id and increase score by one
      const modifiedJokes = state.jokes.map(joke => {
        if (joke.id === id) {
          
          joke.score = joke.score + 1;
          
        }
        return joke;
      });
      console.log(modifiedJokes);
      return { jokes: modifiedJokes };
    });
  }
render() {
    return (
      <div>
        <h1>Container</h1>
        {this.state.jokes.map(joke => (
          <Joke
            key={joke.id}
            id={joke.id}
            joke={joke.joke}
            score={joke.score}
            upVote={this.upVote}
            downVote={this.downVote}
          />
        ))}
      </div>
    );
  }
}

on the other hand if I rewrite the handler this way, then it fires only once

upVote(id) {
    const modifiedJokes = this.state.jokes.map(joke => {
      if (joke.id === id) {
        joke.score = joke.score + 1;
      }
      return joke;
    });
    this.setState({ jokes: modifiedJokes });
  };

Advertisement

Answer

My best guess is that in the first case, you are also modifying the state directly, when you do joke.score = joke.score + 1;

Because you are doing this mapping directly on state array variable, and in Javascript, when using array, you are only working with pointer to that array, not creating a copy of that array.

So the mapping function probably takes a shallow copy of the array, and there’s where problem happens.

You can use lodash to create a deep copy of the state array before you going to work with it, which will not cause your problem:

https://codesandbox.io/s/great-babbage-lorlm

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement