React - Would'nt React.PureComponent or shouldComponentUpdate always result in not re -rendering if dealing...
I found a lot of posts regarding PureComponents shallow comparison but wonder the following:
If React.PureComponent or shouldComponentUpdate only does shallow comparison - wouldnt it mean that if I pass an object via props or compare my state to nextState (which is an object) that it would always result in false even if properties of that object have changed (since its still pointing to the same object and no comparison of the properties is being done), thus, my component would not re-render?
reactjs
add a comment |
I found a lot of posts regarding PureComponents shallow comparison but wonder the following:
If React.PureComponent or shouldComponentUpdate only does shallow comparison - wouldnt it mean that if I pass an object via props or compare my state to nextState (which is an object) that it would always result in false even if properties of that object have changed (since its still pointing to the same object and no comparison of the properties is being done), thus, my component would not re-render?
reactjs
add a comment |
I found a lot of posts regarding PureComponents shallow comparison but wonder the following:
If React.PureComponent or shouldComponentUpdate only does shallow comparison - wouldnt it mean that if I pass an object via props or compare my state to nextState (which is an object) that it would always result in false even if properties of that object have changed (since its still pointing to the same object and no comparison of the properties is being done), thus, my component would not re-render?
reactjs
I found a lot of posts regarding PureComponents shallow comparison but wonder the following:
If React.PureComponent or shouldComponentUpdate only does shallow comparison - wouldnt it mean that if I pass an object via props or compare my state to nextState (which is an object) that it would always result in false even if properties of that object have changed (since its still pointing to the same object and no comparison of the properties is being done), thus, my component would not re-render?
reactjs
reactjs
asked Nov 12 '18 at 12:10
javascripting
229317
229317
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
Yes, you may get into case when render is not called since object is the same. Even official docs suggest not passing object values into PureComponent
.
Only extend PureComponent when you expect to have simple props and state, or use forceUpdate() when you know deep data structures have changed. Or, consider using immutable objects to facilitate fast comparisons of nested data.
But this will work once you avoid mutating this object passed to props
in parent component.
If you follow the way as redux‘s reducers do(return new object once anything inside is changed) you will be fine.
But again since it requires additionally attention from anybody it's safer just avoid passing objects and explode all data in list of primitive values passed independently
[UPD] let's take a look into few examples for Parent component's code:
Here MyPure will always re-render because it's different object passed each time:
render() {
let childData = {....};
....
return (
....
<MyPure data={childData} />
Here MyPure
will never be re-rendered because this.childData
is shallowly the same:
changeChild = () => {
this.childData.a++;
}
render() {
....
return (
....
<MyPure data={this.childData} />
This will work well since we are updating different object only after updating something inside:
changeChild = () => {
this.setState(oldState => ({
childData: {
...oldState.childData,
a: oldState.childData.a + 1
}
}));
}
render() {
....
return (
....
<MyPure data={this.state.childData} />
So there are few restrictions we need to follow:
1. don't construct data prop in render()
(explicitly or implicitly through calling separated method)
2. don't mutate object data prop
Thanks! you mentioned returning new object like redux , but how would that even look like when passing an object via props?parent component would return new object, then pass it to child?! but then the comparison would ALWAYS result in true meaning a re-render would always happen. Thus, using PureComponent or shouldComponentUpdate for objects will either ALWAYS result in false/always re-rendering (if I dont return new object) OR ALWAYS in true meaning a re-render will NEVER happen?! So, I should ONLY use it for primitive values or immutable data or i will garantied (at some point) get bugs
– javascripting
Nov 12 '18 at 13:46
I've appended my answer with examples
– skyboyer
Nov 12 '18 at 13:56
Thank you!! A question: if I always create a new object on each setState call, wouldnt the benefit of performance increase by using React.PureComponent be 'topped' by too much memory allocation?
– javascripting
Nov 12 '18 at 15:02
cannot say without looking into concrete code. typicallyPureComponent
is introduced on purpose for components that have heavyrender()
. So you should already know way how to ensure this optimization makes sense for your project.
– skyboyer
Nov 12 '18 at 15:21
add a comment |
The shallow comparison will be of the first level of properties within an object. For state, it should NOT be the same object, since you should always call setState with a new object. You should not directly mutate the existing state.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53261928%2freact-wouldnt-react-purecomponent-or-shouldcomponentupdate-always-result-in-n%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Yes, you may get into case when render is not called since object is the same. Even official docs suggest not passing object values into PureComponent
.
Only extend PureComponent when you expect to have simple props and state, or use forceUpdate() when you know deep data structures have changed. Or, consider using immutable objects to facilitate fast comparisons of nested data.
But this will work once you avoid mutating this object passed to props
in parent component.
If you follow the way as redux‘s reducers do(return new object once anything inside is changed) you will be fine.
But again since it requires additionally attention from anybody it's safer just avoid passing objects and explode all data in list of primitive values passed independently
[UPD] let's take a look into few examples for Parent component's code:
Here MyPure will always re-render because it's different object passed each time:
render() {
let childData = {....};
....
return (
....
<MyPure data={childData} />
Here MyPure
will never be re-rendered because this.childData
is shallowly the same:
changeChild = () => {
this.childData.a++;
}
render() {
....
return (
....
<MyPure data={this.childData} />
This will work well since we are updating different object only after updating something inside:
changeChild = () => {
this.setState(oldState => ({
childData: {
...oldState.childData,
a: oldState.childData.a + 1
}
}));
}
render() {
....
return (
....
<MyPure data={this.state.childData} />
So there are few restrictions we need to follow:
1. don't construct data prop in render()
(explicitly or implicitly through calling separated method)
2. don't mutate object data prop
Thanks! you mentioned returning new object like redux , but how would that even look like when passing an object via props?parent component would return new object, then pass it to child?! but then the comparison would ALWAYS result in true meaning a re-render would always happen. Thus, using PureComponent or shouldComponentUpdate for objects will either ALWAYS result in false/always re-rendering (if I dont return new object) OR ALWAYS in true meaning a re-render will NEVER happen?! So, I should ONLY use it for primitive values or immutable data or i will garantied (at some point) get bugs
– javascripting
Nov 12 '18 at 13:46
I've appended my answer with examples
– skyboyer
Nov 12 '18 at 13:56
Thank you!! A question: if I always create a new object on each setState call, wouldnt the benefit of performance increase by using React.PureComponent be 'topped' by too much memory allocation?
– javascripting
Nov 12 '18 at 15:02
cannot say without looking into concrete code. typicallyPureComponent
is introduced on purpose for components that have heavyrender()
. So you should already know way how to ensure this optimization makes sense for your project.
– skyboyer
Nov 12 '18 at 15:21
add a comment |
Yes, you may get into case when render is not called since object is the same. Even official docs suggest not passing object values into PureComponent
.
Only extend PureComponent when you expect to have simple props and state, or use forceUpdate() when you know deep data structures have changed. Or, consider using immutable objects to facilitate fast comparisons of nested data.
But this will work once you avoid mutating this object passed to props
in parent component.
If you follow the way as redux‘s reducers do(return new object once anything inside is changed) you will be fine.
But again since it requires additionally attention from anybody it's safer just avoid passing objects and explode all data in list of primitive values passed independently
[UPD] let's take a look into few examples for Parent component's code:
Here MyPure will always re-render because it's different object passed each time:
render() {
let childData = {....};
....
return (
....
<MyPure data={childData} />
Here MyPure
will never be re-rendered because this.childData
is shallowly the same:
changeChild = () => {
this.childData.a++;
}
render() {
....
return (
....
<MyPure data={this.childData} />
This will work well since we are updating different object only after updating something inside:
changeChild = () => {
this.setState(oldState => ({
childData: {
...oldState.childData,
a: oldState.childData.a + 1
}
}));
}
render() {
....
return (
....
<MyPure data={this.state.childData} />
So there are few restrictions we need to follow:
1. don't construct data prop in render()
(explicitly or implicitly through calling separated method)
2. don't mutate object data prop
Thanks! you mentioned returning new object like redux , but how would that even look like when passing an object via props?parent component would return new object, then pass it to child?! but then the comparison would ALWAYS result in true meaning a re-render would always happen. Thus, using PureComponent or shouldComponentUpdate for objects will either ALWAYS result in false/always re-rendering (if I dont return new object) OR ALWAYS in true meaning a re-render will NEVER happen?! So, I should ONLY use it for primitive values or immutable data or i will garantied (at some point) get bugs
– javascripting
Nov 12 '18 at 13:46
I've appended my answer with examples
– skyboyer
Nov 12 '18 at 13:56
Thank you!! A question: if I always create a new object on each setState call, wouldnt the benefit of performance increase by using React.PureComponent be 'topped' by too much memory allocation?
– javascripting
Nov 12 '18 at 15:02
cannot say without looking into concrete code. typicallyPureComponent
is introduced on purpose for components that have heavyrender()
. So you should already know way how to ensure this optimization makes sense for your project.
– skyboyer
Nov 12 '18 at 15:21
add a comment |
Yes, you may get into case when render is not called since object is the same. Even official docs suggest not passing object values into PureComponent
.
Only extend PureComponent when you expect to have simple props and state, or use forceUpdate() when you know deep data structures have changed. Or, consider using immutable objects to facilitate fast comparisons of nested data.
But this will work once you avoid mutating this object passed to props
in parent component.
If you follow the way as redux‘s reducers do(return new object once anything inside is changed) you will be fine.
But again since it requires additionally attention from anybody it's safer just avoid passing objects and explode all data in list of primitive values passed independently
[UPD] let's take a look into few examples for Parent component's code:
Here MyPure will always re-render because it's different object passed each time:
render() {
let childData = {....};
....
return (
....
<MyPure data={childData} />
Here MyPure
will never be re-rendered because this.childData
is shallowly the same:
changeChild = () => {
this.childData.a++;
}
render() {
....
return (
....
<MyPure data={this.childData} />
This will work well since we are updating different object only after updating something inside:
changeChild = () => {
this.setState(oldState => ({
childData: {
...oldState.childData,
a: oldState.childData.a + 1
}
}));
}
render() {
....
return (
....
<MyPure data={this.state.childData} />
So there are few restrictions we need to follow:
1. don't construct data prop in render()
(explicitly or implicitly through calling separated method)
2. don't mutate object data prop
Yes, you may get into case when render is not called since object is the same. Even official docs suggest not passing object values into PureComponent
.
Only extend PureComponent when you expect to have simple props and state, or use forceUpdate() when you know deep data structures have changed. Or, consider using immutable objects to facilitate fast comparisons of nested data.
But this will work once you avoid mutating this object passed to props
in parent component.
If you follow the way as redux‘s reducers do(return new object once anything inside is changed) you will be fine.
But again since it requires additionally attention from anybody it's safer just avoid passing objects and explode all data in list of primitive values passed independently
[UPD] let's take a look into few examples for Parent component's code:
Here MyPure will always re-render because it's different object passed each time:
render() {
let childData = {....};
....
return (
....
<MyPure data={childData} />
Here MyPure
will never be re-rendered because this.childData
is shallowly the same:
changeChild = () => {
this.childData.a++;
}
render() {
....
return (
....
<MyPure data={this.childData} />
This will work well since we are updating different object only after updating something inside:
changeChild = () => {
this.setState(oldState => ({
childData: {
...oldState.childData,
a: oldState.childData.a + 1
}
}));
}
render() {
....
return (
....
<MyPure data={this.state.childData} />
So there are few restrictions we need to follow:
1. don't construct data prop in render()
(explicitly or implicitly through calling separated method)
2. don't mutate object data prop
edited Nov 12 '18 at 13:56
answered Nov 12 '18 at 12:37
skyboyer
3,32111128
3,32111128
Thanks! you mentioned returning new object like redux , but how would that even look like when passing an object via props?parent component would return new object, then pass it to child?! but then the comparison would ALWAYS result in true meaning a re-render would always happen. Thus, using PureComponent or shouldComponentUpdate for objects will either ALWAYS result in false/always re-rendering (if I dont return new object) OR ALWAYS in true meaning a re-render will NEVER happen?! So, I should ONLY use it for primitive values or immutable data or i will garantied (at some point) get bugs
– javascripting
Nov 12 '18 at 13:46
I've appended my answer with examples
– skyboyer
Nov 12 '18 at 13:56
Thank you!! A question: if I always create a new object on each setState call, wouldnt the benefit of performance increase by using React.PureComponent be 'topped' by too much memory allocation?
– javascripting
Nov 12 '18 at 15:02
cannot say without looking into concrete code. typicallyPureComponent
is introduced on purpose for components that have heavyrender()
. So you should already know way how to ensure this optimization makes sense for your project.
– skyboyer
Nov 12 '18 at 15:21
add a comment |
Thanks! you mentioned returning new object like redux , but how would that even look like when passing an object via props?parent component would return new object, then pass it to child?! but then the comparison would ALWAYS result in true meaning a re-render would always happen. Thus, using PureComponent or shouldComponentUpdate for objects will either ALWAYS result in false/always re-rendering (if I dont return new object) OR ALWAYS in true meaning a re-render will NEVER happen?! So, I should ONLY use it for primitive values or immutable data or i will garantied (at some point) get bugs
– javascripting
Nov 12 '18 at 13:46
I've appended my answer with examples
– skyboyer
Nov 12 '18 at 13:56
Thank you!! A question: if I always create a new object on each setState call, wouldnt the benefit of performance increase by using React.PureComponent be 'topped' by too much memory allocation?
– javascripting
Nov 12 '18 at 15:02
cannot say without looking into concrete code. typicallyPureComponent
is introduced on purpose for components that have heavyrender()
. So you should already know way how to ensure this optimization makes sense for your project.
– skyboyer
Nov 12 '18 at 15:21
Thanks! you mentioned returning new object like redux , but how would that even look like when passing an object via props?parent component would return new object, then pass it to child?! but then the comparison would ALWAYS result in true meaning a re-render would always happen. Thus, using PureComponent or shouldComponentUpdate for objects will either ALWAYS result in false/always re-rendering (if I dont return new object) OR ALWAYS in true meaning a re-render will NEVER happen?! So, I should ONLY use it for primitive values or immutable data or i will garantied (at some point) get bugs
– javascripting
Nov 12 '18 at 13:46
Thanks! you mentioned returning new object like redux , but how would that even look like when passing an object via props?parent component would return new object, then pass it to child?! but then the comparison would ALWAYS result in true meaning a re-render would always happen. Thus, using PureComponent or shouldComponentUpdate for objects will either ALWAYS result in false/always re-rendering (if I dont return new object) OR ALWAYS in true meaning a re-render will NEVER happen?! So, I should ONLY use it for primitive values or immutable data or i will garantied (at some point) get bugs
– javascripting
Nov 12 '18 at 13:46
I've appended my answer with examples
– skyboyer
Nov 12 '18 at 13:56
I've appended my answer with examples
– skyboyer
Nov 12 '18 at 13:56
Thank you!! A question: if I always create a new object on each setState call, wouldnt the benefit of performance increase by using React.PureComponent be 'topped' by too much memory allocation?
– javascripting
Nov 12 '18 at 15:02
Thank you!! A question: if I always create a new object on each setState call, wouldnt the benefit of performance increase by using React.PureComponent be 'topped' by too much memory allocation?
– javascripting
Nov 12 '18 at 15:02
cannot say without looking into concrete code. typically
PureComponent
is introduced on purpose for components that have heavy render()
. So you should already know way how to ensure this optimization makes sense for your project.– skyboyer
Nov 12 '18 at 15:21
cannot say without looking into concrete code. typically
PureComponent
is introduced on purpose for components that have heavy render()
. So you should already know way how to ensure this optimization makes sense for your project.– skyboyer
Nov 12 '18 at 15:21
add a comment |
The shallow comparison will be of the first level of properties within an object. For state, it should NOT be the same object, since you should always call setState with a new object. You should not directly mutate the existing state.
add a comment |
The shallow comparison will be of the first level of properties within an object. For state, it should NOT be the same object, since you should always call setState with a new object. You should not directly mutate the existing state.
add a comment |
The shallow comparison will be of the first level of properties within an object. For state, it should NOT be the same object, since you should always call setState with a new object. You should not directly mutate the existing state.
The shallow comparison will be of the first level of properties within an object. For state, it should NOT be the same object, since you should always call setState with a new object. You should not directly mutate the existing state.
answered Nov 12 '18 at 12:25
Ryan Cogswell
1,372211
1,372211
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53261928%2freact-wouldnt-react-purecomponent-or-shouldcomponentupdate-always-result-in-n%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown