React compresses rendering, causing not updating components even if componentDidUpdate called
The React parent component rendering process automatically compresses rendering of child components. It can be a performance boost for most of application, but situation like this can be a serious problem.
I have 2 components :
- File list sidebar component
- Text editor component (I'm using Slate for now)
Two component is child component of Home component.
When user clicks the sidebar item, it should :
- Highlight the selected item
- Set a new editor state by reading the text file
Second step can be a bottleneck. The problem here is, that the React stupidly compresses the seperated two operations altogether.
This causes the user can't see item highlight right after click! User Must wait for reading the file, and set a new editor state, and then, finally, item can get highlighted.
This delay, is causing badly at user experience. Did you ever used a text editor that reacts your click about ~500ms after? The program looks "slower".
componentDidUpdate(prevProps) {
console.log('componentDidUpdate!');
const { currentDir, actions, currentFile } = this.props;
if (prevProps.currentDir !== currentDir) {
updatedFileList(currentDir);
} else if (prevProps.currentFile !== currentFile) {
updateEditorContent(currentFile);
}
}
This is the componentDidUpdate. This updates editor state.
redux-logger.js:1 action SELECT_FILE_LIST_ITEM @ 21:29:18.332
21:29:18.338 redux-logger.js:1 action UPDATE_CURRENT_FILE @ 21:29:18.338
21:29:18.347 Home.js:287 render!!
21:29:18.356 Home.js:44 componentDidUpdate!
21:29:18.366 redux-logger.js:1 action UPDATE_EDITOR_CONTENT @ 21:29:18.357
21:29:18.373 Home.js:287 render!!
21:29:18.678 Home.js:44 componentDidUpdate!
The log says it componentDidUpdate
d at 21:29:18.356
, but actual HTML DOM is not updated yet. It acutally updates DOM after 21:29:18.678 Home.js:44 componentDidUpdate!
.'
How to seperate two componentDidUpdates, to update DOM seperately?
javascript reactjs redux react-redux
add a comment |
The React parent component rendering process automatically compresses rendering of child components. It can be a performance boost for most of application, but situation like this can be a serious problem.
I have 2 components :
- File list sidebar component
- Text editor component (I'm using Slate for now)
Two component is child component of Home component.
When user clicks the sidebar item, it should :
- Highlight the selected item
- Set a new editor state by reading the text file
Second step can be a bottleneck. The problem here is, that the React stupidly compresses the seperated two operations altogether.
This causes the user can't see item highlight right after click! User Must wait for reading the file, and set a new editor state, and then, finally, item can get highlighted.
This delay, is causing badly at user experience. Did you ever used a text editor that reacts your click about ~500ms after? The program looks "slower".
componentDidUpdate(prevProps) {
console.log('componentDidUpdate!');
const { currentDir, actions, currentFile } = this.props;
if (prevProps.currentDir !== currentDir) {
updatedFileList(currentDir);
} else if (prevProps.currentFile !== currentFile) {
updateEditorContent(currentFile);
}
}
This is the componentDidUpdate. This updates editor state.
redux-logger.js:1 action SELECT_FILE_LIST_ITEM @ 21:29:18.332
21:29:18.338 redux-logger.js:1 action UPDATE_CURRENT_FILE @ 21:29:18.338
21:29:18.347 Home.js:287 render!!
21:29:18.356 Home.js:44 componentDidUpdate!
21:29:18.366 redux-logger.js:1 action UPDATE_EDITOR_CONTENT @ 21:29:18.357
21:29:18.373 Home.js:287 render!!
21:29:18.678 Home.js:44 componentDidUpdate!
The log says it componentDidUpdate
d at 21:29:18.356
, but actual HTML DOM is not updated yet. It acutally updates DOM after 21:29:18.678 Home.js:44 componentDidUpdate!
.'
How to seperate two componentDidUpdates, to update DOM seperately?
javascript reactjs redux react-redux
add a comment |
The React parent component rendering process automatically compresses rendering of child components. It can be a performance boost for most of application, but situation like this can be a serious problem.
I have 2 components :
- File list sidebar component
- Text editor component (I'm using Slate for now)
Two component is child component of Home component.
When user clicks the sidebar item, it should :
- Highlight the selected item
- Set a new editor state by reading the text file
Second step can be a bottleneck. The problem here is, that the React stupidly compresses the seperated two operations altogether.
This causes the user can't see item highlight right after click! User Must wait for reading the file, and set a new editor state, and then, finally, item can get highlighted.
This delay, is causing badly at user experience. Did you ever used a text editor that reacts your click about ~500ms after? The program looks "slower".
componentDidUpdate(prevProps) {
console.log('componentDidUpdate!');
const { currentDir, actions, currentFile } = this.props;
if (prevProps.currentDir !== currentDir) {
updatedFileList(currentDir);
} else if (prevProps.currentFile !== currentFile) {
updateEditorContent(currentFile);
}
}
This is the componentDidUpdate. This updates editor state.
redux-logger.js:1 action SELECT_FILE_LIST_ITEM @ 21:29:18.332
21:29:18.338 redux-logger.js:1 action UPDATE_CURRENT_FILE @ 21:29:18.338
21:29:18.347 Home.js:287 render!!
21:29:18.356 Home.js:44 componentDidUpdate!
21:29:18.366 redux-logger.js:1 action UPDATE_EDITOR_CONTENT @ 21:29:18.357
21:29:18.373 Home.js:287 render!!
21:29:18.678 Home.js:44 componentDidUpdate!
The log says it componentDidUpdate
d at 21:29:18.356
, but actual HTML DOM is not updated yet. It acutally updates DOM after 21:29:18.678 Home.js:44 componentDidUpdate!
.'
How to seperate two componentDidUpdates, to update DOM seperately?
javascript reactjs redux react-redux
The React parent component rendering process automatically compresses rendering of child components. It can be a performance boost for most of application, but situation like this can be a serious problem.
I have 2 components :
- File list sidebar component
- Text editor component (I'm using Slate for now)
Two component is child component of Home component.
When user clicks the sidebar item, it should :
- Highlight the selected item
- Set a new editor state by reading the text file
Second step can be a bottleneck. The problem here is, that the React stupidly compresses the seperated two operations altogether.
This causes the user can't see item highlight right after click! User Must wait for reading the file, and set a new editor state, and then, finally, item can get highlighted.
This delay, is causing badly at user experience. Did you ever used a text editor that reacts your click about ~500ms after? The program looks "slower".
componentDidUpdate(prevProps) {
console.log('componentDidUpdate!');
const { currentDir, actions, currentFile } = this.props;
if (prevProps.currentDir !== currentDir) {
updatedFileList(currentDir);
} else if (prevProps.currentFile !== currentFile) {
updateEditorContent(currentFile);
}
}
This is the componentDidUpdate. This updates editor state.
redux-logger.js:1 action SELECT_FILE_LIST_ITEM @ 21:29:18.332
21:29:18.338 redux-logger.js:1 action UPDATE_CURRENT_FILE @ 21:29:18.338
21:29:18.347 Home.js:287 render!!
21:29:18.356 Home.js:44 componentDidUpdate!
21:29:18.366 redux-logger.js:1 action UPDATE_EDITOR_CONTENT @ 21:29:18.357
21:29:18.373 Home.js:287 render!!
21:29:18.678 Home.js:44 componentDidUpdate!
The log says it componentDidUpdate
d at 21:29:18.356
, but actual HTML DOM is not updated yet. It acutally updates DOM after 21:29:18.678 Home.js:44 componentDidUpdate!
.'
How to seperate two componentDidUpdates, to update DOM seperately?
javascript reactjs redux react-redux
javascript reactjs redux react-redux
edited Jan 1 at 12:47
Hoseong Son
asked Jan 1 at 12:28
Hoseong SonHoseong Son
67111
67111
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
I think you should be able to solve this by triggering the second update asynchronously:
componentDidUpdate(prevProps) {
console.log('componentDidUpdate!');
const { currentDir, actions, currentFile } = this.props;
if (prevProps.currentDir !== currentDir) {
updatedFileList(currentDir);
} else if (prevProps.currentFile !== currentFile) {
setTimeout(()=>{updateEditorContent(currentFile);}, 0);
}
}
I didn't actually try this out, so I apologize if there are any syntax issues.
In general, what React is doing is desirable -- not wasting time updating the DOM two times when one state update immediately triggers another state update. This avoids DOM flicker when both updates are quick.
React is able to do this because it splits its work into two phases
- a rendering/reconciliation phase in which React figures out what should be changed with the next update to the DOM
- a commit phase where those updates are actually applied to the DOM
When the rendering triggers another rendering, React will hold off on the commit phase and batch up the DOM updates for one commit. The setTimeout
above will cause that state update to wait until after the commit phase for the first update.
I think future React features around asynchronous mode will provide nicer ways of dealing with this kind of scenario where one update is high priority and the other is lower priority.
You're right. That solves the problem. But, I want to know the under the hood. I'm React noob, so could you please explain the how asynchronizing the state update can make a seperate React DOM update?
– Hoseong Son
Jan 1 at 12:59
1
I've updated my answer to explain this further. You can find more detail in some links about the React Fiber Reconciler at the end of my answer here: stackoverflow.com/questions/53974865/…
– Ryan Cogswell
Jan 1 at 13:12
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%2f53995431%2freact-compresses-rendering-causing-not-updating-components-even-if-componentdid%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I think you should be able to solve this by triggering the second update asynchronously:
componentDidUpdate(prevProps) {
console.log('componentDidUpdate!');
const { currentDir, actions, currentFile } = this.props;
if (prevProps.currentDir !== currentDir) {
updatedFileList(currentDir);
} else if (prevProps.currentFile !== currentFile) {
setTimeout(()=>{updateEditorContent(currentFile);}, 0);
}
}
I didn't actually try this out, so I apologize if there are any syntax issues.
In general, what React is doing is desirable -- not wasting time updating the DOM two times when one state update immediately triggers another state update. This avoids DOM flicker when both updates are quick.
React is able to do this because it splits its work into two phases
- a rendering/reconciliation phase in which React figures out what should be changed with the next update to the DOM
- a commit phase where those updates are actually applied to the DOM
When the rendering triggers another rendering, React will hold off on the commit phase and batch up the DOM updates for one commit. The setTimeout
above will cause that state update to wait until after the commit phase for the first update.
I think future React features around asynchronous mode will provide nicer ways of dealing with this kind of scenario where one update is high priority and the other is lower priority.
You're right. That solves the problem. But, I want to know the under the hood. I'm React noob, so could you please explain the how asynchronizing the state update can make a seperate React DOM update?
– Hoseong Son
Jan 1 at 12:59
1
I've updated my answer to explain this further. You can find more detail in some links about the React Fiber Reconciler at the end of my answer here: stackoverflow.com/questions/53974865/…
– Ryan Cogswell
Jan 1 at 13:12
add a comment |
I think you should be able to solve this by triggering the second update asynchronously:
componentDidUpdate(prevProps) {
console.log('componentDidUpdate!');
const { currentDir, actions, currentFile } = this.props;
if (prevProps.currentDir !== currentDir) {
updatedFileList(currentDir);
} else if (prevProps.currentFile !== currentFile) {
setTimeout(()=>{updateEditorContent(currentFile);}, 0);
}
}
I didn't actually try this out, so I apologize if there are any syntax issues.
In general, what React is doing is desirable -- not wasting time updating the DOM two times when one state update immediately triggers another state update. This avoids DOM flicker when both updates are quick.
React is able to do this because it splits its work into two phases
- a rendering/reconciliation phase in which React figures out what should be changed with the next update to the DOM
- a commit phase where those updates are actually applied to the DOM
When the rendering triggers another rendering, React will hold off on the commit phase and batch up the DOM updates for one commit. The setTimeout
above will cause that state update to wait until after the commit phase for the first update.
I think future React features around asynchronous mode will provide nicer ways of dealing with this kind of scenario where one update is high priority and the other is lower priority.
You're right. That solves the problem. But, I want to know the under the hood. I'm React noob, so could you please explain the how asynchronizing the state update can make a seperate React DOM update?
– Hoseong Son
Jan 1 at 12:59
1
I've updated my answer to explain this further. You can find more detail in some links about the React Fiber Reconciler at the end of my answer here: stackoverflow.com/questions/53974865/…
– Ryan Cogswell
Jan 1 at 13:12
add a comment |
I think you should be able to solve this by triggering the second update asynchronously:
componentDidUpdate(prevProps) {
console.log('componentDidUpdate!');
const { currentDir, actions, currentFile } = this.props;
if (prevProps.currentDir !== currentDir) {
updatedFileList(currentDir);
} else if (prevProps.currentFile !== currentFile) {
setTimeout(()=>{updateEditorContent(currentFile);}, 0);
}
}
I didn't actually try this out, so I apologize if there are any syntax issues.
In general, what React is doing is desirable -- not wasting time updating the DOM two times when one state update immediately triggers another state update. This avoids DOM flicker when both updates are quick.
React is able to do this because it splits its work into two phases
- a rendering/reconciliation phase in which React figures out what should be changed with the next update to the DOM
- a commit phase where those updates are actually applied to the DOM
When the rendering triggers another rendering, React will hold off on the commit phase and batch up the DOM updates for one commit. The setTimeout
above will cause that state update to wait until after the commit phase for the first update.
I think future React features around asynchronous mode will provide nicer ways of dealing with this kind of scenario where one update is high priority and the other is lower priority.
I think you should be able to solve this by triggering the second update asynchronously:
componentDidUpdate(prevProps) {
console.log('componentDidUpdate!');
const { currentDir, actions, currentFile } = this.props;
if (prevProps.currentDir !== currentDir) {
updatedFileList(currentDir);
} else if (prevProps.currentFile !== currentFile) {
setTimeout(()=>{updateEditorContent(currentFile);}, 0);
}
}
I didn't actually try this out, so I apologize if there are any syntax issues.
In general, what React is doing is desirable -- not wasting time updating the DOM two times when one state update immediately triggers another state update. This avoids DOM flicker when both updates are quick.
React is able to do this because it splits its work into two phases
- a rendering/reconciliation phase in which React figures out what should be changed with the next update to the DOM
- a commit phase where those updates are actually applied to the DOM
When the rendering triggers another rendering, React will hold off on the commit phase and batch up the DOM updates for one commit. The setTimeout
above will cause that state update to wait until after the commit phase for the first update.
I think future React features around asynchronous mode will provide nicer ways of dealing with this kind of scenario where one update is high priority and the other is lower priority.
edited Jan 1 at 13:11
answered Jan 1 at 12:50


Ryan CogswellRyan Cogswell
5,066524
5,066524
You're right. That solves the problem. But, I want to know the under the hood. I'm React noob, so could you please explain the how asynchronizing the state update can make a seperate React DOM update?
– Hoseong Son
Jan 1 at 12:59
1
I've updated my answer to explain this further. You can find more detail in some links about the React Fiber Reconciler at the end of my answer here: stackoverflow.com/questions/53974865/…
– Ryan Cogswell
Jan 1 at 13:12
add a comment |
You're right. That solves the problem. But, I want to know the under the hood. I'm React noob, so could you please explain the how asynchronizing the state update can make a seperate React DOM update?
– Hoseong Son
Jan 1 at 12:59
1
I've updated my answer to explain this further. You can find more detail in some links about the React Fiber Reconciler at the end of my answer here: stackoverflow.com/questions/53974865/…
– Ryan Cogswell
Jan 1 at 13:12
You're right. That solves the problem. But, I want to know the under the hood. I'm React noob, so could you please explain the how asynchronizing the state update can make a seperate React DOM update?
– Hoseong Son
Jan 1 at 12:59
You're right. That solves the problem. But, I want to know the under the hood. I'm React noob, so could you please explain the how asynchronizing the state update can make a seperate React DOM update?
– Hoseong Son
Jan 1 at 12:59
1
1
I've updated my answer to explain this further. You can find more detail in some links about the React Fiber Reconciler at the end of my answer here: stackoverflow.com/questions/53974865/…
– Ryan Cogswell
Jan 1 at 13:12
I've updated my answer to explain this further. You can find more detail in some links about the React Fiber Reconciler at the end of my answer here: stackoverflow.com/questions/53974865/…
– Ryan Cogswell
Jan 1 at 13:12
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.
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%2f53995431%2freact-compresses-rendering-causing-not-updating-components-even-if-componentdid%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