boosted_duck
boosted_duck

Reputation: 498

React shouldComponentUpdate returns true when the props has a function or method call

Please help me understand why shouldComponentUpdate() in Person.js returns true when the props I am passing to it has a method from App.js even though that method did not change at all.

This is the code from my App.js

return <Person 
            name={cur.name} 
            age={cur.age} 
            job={cur.job} 
            key={cur.id} 
            change={(event) => this.changeName(event, cur.id)} 
            delete={(event) => this.deletePerson(cur.id)} 
        />;

This is the code from my Person.js

shouldComponentUpdate(nextProps, nextState) {
        console.log(`[Person component] shouldComponentUpdate()`);
        console.log(this.props);
        console.log(nextProps);
        console.log(nextProps.name !== this.props.name || nextProps.age !== this.props.age || nextProps.job !== this.props.job);
        console.log(nextProps.delete !== this.props.delete);
        console.log(`------------------------`);
        console.log(this.props.delete);
        console.log(nextProps.delete);
        return nextProps !== this.props;
    }

The

console.log(nextProps.name !== this.props.name || nextProps.age !== this.props.age || nextProps.job !== this.props.job);
            console.log(nextProps.delete !== this.props.delete);

Returns false as expected, but the console.log(nextProps.delete !== this.props.delete); always returns true even though I've deleted all the codes in App.js deletePerson() method.

Why is that?

Upvotes: 0

Views: 589

Answers (1)

Chaim Friedman
Chaim Friedman

Reputation: 6253

When you pass a function like so () => someFunc() you are essentially creating a new function on each render. So while the function still does the same thing, in memory its actually a new function.

I would recommend giving this article a quick read thru to see more details about this issue and some solutions.

A common case where passing a new function is the go to, is when the function requires some sort of argument to be passed in to it, for example, an id to know which item to delete. A common solution is to pass the id as a prop down to the component along with the function. It would look a little something like this.

<Component 
  id={id}
  delete={deleteFunc}
/>

function Component(props) {

  const deleteItem() {
    props.delete(props.id);
  }

  return (
    <button onClick={deleteItem}>
      Delete
    </button>
  );
}

In this case, the function will always be the same, and we can still have the function accept the arguments it requires.

Upvotes: 1

Related Questions