develdevil
develdevil

Reputation: 327

Will a React component re-render if its props are updated, but don't change in value?

Let's say we've got a redux store that looks like this:

{
  "page1": {
    "title": "Demo",
    "content": "Testing"
  },
  "page2": {
    "title": "Demo",
    "content": "Yes, I'm aware the titles match."
  }
}

Now let's look at the component that renders the title:

const Title = ({title}) => <h1>{title}</h1>

const mapStateToProps = state => ({
  title: getCurrentPage().title
})

export default connect(mapStateToProps)(Title)

In the above block, getCurrentPage() is a memoized function (via reselect) that derives the current page data from the state based on some condition (in this case, it's react-router's location.pathname).

Will this component re-render when the data returned by getCurrentPage() is different, even though the specific value of {title} stays the same?

If yes, will memoizing the derived title prop change the answer to no?

Upvotes: 1

Views: 3052

Answers (3)

Benjamin Hao
Benjamin Hao

Reputation: 338

The component will re-render if the props changed, or the local state changed due to a call to setState(), or you explicitly call the foceUpdate() function. In your case, the title is a string, and the old string and new string have the same value, so, there is no change in the props, therefore no re-render.

One thing to be careful is passing an object to a props. react won't do a deep comparison, so the result may be different from your expectation. In that case, you need to compare the old and new objects by yourself in the getDerivedStateFromProps or componentWillRecieveProps in old versions, and then decide whether you need to call forceUpdate() to force the component to re-render.

Upvotes: 1

StefanBD
StefanBD

Reputation: 344

in my tests not with redux and object it does and i had add a check comand to my compoments for only updating when real change.

Btw why not test with a simple console.log?

Upvotes: 0

develdevil
develdevil

Reputation: 327

Ok, I took the time to test out my own question because the first answer I received said it would re-render. I inserted console.log('render') into the Title component and then navigated between two separate pages that each shared the same exact title. And the result... (drum roll)

NO. The component did not re-render.

Upvotes: 4

Related Questions