-
Notifications
You must be signed in to change notification settings - Fork 47k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Children don't re-render when parent component is optimised #6515
Comments
This is a usage question, rather than a bug in React. Your Optimizing components that can take in arbitrary children is somewhat non-trivial. In general, it will require walking/diffing the children in some way, and (for completely general children) this is technically not possible for the same reasons that Also, keep in mind that Anyway, I'm going to close out the issue, since it's not a bug in React. Feel free to continue the discussion on this thread, or move the discussion to StackOverflow. |
This might be an inconvenience or even a conceptual problem, but definitely not a bug. shouldComponentUpdate(nextProps) {
// naïve, only for demo purpose
return nextProps.color !== this.props.color;
// how to optimize this for children??
// it doesn't make sense for it to have to check for its
// children, as it's simple composition, it shouldn't
// have to care about what is passed through it.
} Indeed, just This begs the question: isn’t this negating the benefits of There was some discussion about taking |
@gaearon I realise this implementation is naïve, and it does make sense when thinking about the fact that even though children are passed from the outside, they are only rendered within the parent's render function, wherever you're going to do To be clear, this example was obviously very contrived and doesn't really make sense on its own as you probably wouldn't try to optimise things in this case. In my real scenario, I'm however having to deal with trying to optimise things on hundreds of these components. To give a bit more insight into what I'm building: I am building a low level performant grid component (similar to FixedDataTable ) that can handle thousands of rows and columns, as well as handling lots of realtime updates. I am using Immutable.js for the data so that it's easier and more efficient to handle. My problem appeared when I changed the top level Using getters at the top level component meant it was easy to optimise my From there came the idea to be able to pass your own custom components in the same fashion as FixedDataTable. But I can't seem to be able to stop everything re-rendering even when not needed (especially for example when scrolling as After all your comments regarding how technically difficult it would be to optimise To me the whole point of being able to pass children from outside, or even as props is that you can easily compose things and separate concerns and responsibilities. @gaearon, you mention this:
How would you do this in practice? I understand It does feel like it negates the benefits of |
For your use case, you can take the same approach (I believe?) that FixedDataTable takes. Rather than accept render() {
return (
<MyTable
renderRow={this.renderRow}
renderHeader={this.renderHeader}
/>
)
} Make sure the function references don’t change on every render (just don’t bind them in renderRow() {
// won’t update
return <CustomRow data={this.state.data} />
} To work around it, make any necessary data props to your table so that it can pass them back to the render() {
return (
<MyTable
renderRow={this.renderRow}
renderHeader={this.renderHeader}
data={this.state.data}
/>
)
}
renderRow(data) {
return <CustomRow data={data} />
} This way, unless
Yes, however, most components in my experience don’t take custom |
So you mean passing a render callback? Isn't that considered an anti-pattern? |
Anti-pattern is a loaded word. It’s a tool; like any tool it has upsides and downsides. In this particular case I think it’s very appropriate. |
Well, some anti-patterns are just bad, always. But I wouldn't classify passing a render callback as an anti-pattern, I'd just classify it as a pattern. The pattern is used pretty commonly when a parent needs to pass necessary info to an unowned child. I think it's at least as good as cloning elements or using context. |
What I meant was, doesn't passing a render component makes the component inherently impure? As now the render callback has access to all sorts of outside variables the function has closed on? Meaning shouldComponentUpdate wouldn't help here? |
As long as the callback is pure, everything remains pure. The component is still a function of props (even though the prop happens to be a pure function).
|
@gaearon I've updated the example here with the suggested technique: http://www.webpackbin.com/EJtN1ctk- Although it works, I feel like now we've basically broken encapsulation and made I understand that if you were to render arbitrary children in the render callback now it's somewhat practical, but considering this current example of just a string, how is it different from making the What I mean is that now the |
The way I see it, you don’t get the render thousands of rows and keep perfect encapsulation 😄 . Something’s gotta give. That said I don’t see where the encapsulation is breaking. If you rename it from |
We came across this issue as well and we decided to solve it! |
Bumps [axios](https://github.com/axios/axios) from 1.7.1 to 1.7.4. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/axios/axios/releases">axios's releases</a>.</em></p> <blockquote> <h2>Release v1.7.4</h2> <h2>Release notes:</h2> <h3>Bug Fixes</h3> <ul> <li><strong>sec:</strong> CVE-2024-39338 (<a href="https://redirect.github.com/axios/axios/issues/6539">#6539</a>) (<a href="https://redirect.github.com/axios/axios/issues/6543">#6543</a>) (<a href="https://github.com/axios/axios/commit/6b6b605eaf73852fb2dae033f1e786155959de3a">6b6b605</a>)</li> <li><strong>sec:</strong> disregard protocol-relative URL to remediate SSRF (<a href="https://redirect.github.com/axios/axios/issues/6539">#6539</a>) (<a href="https://github.com/axios/axios/commit/07a661a2a6b9092c4aa640dcc7f724ec5e65bdda">07a661a</a>)</li> </ul> <h3>Contributors to this release</h3> <ul> <li><!-- raw HTML omitted --> <a href="https://github.com/levpachmanov" title="+47/-11 ([#6543](axios/axios#6543) )">Lev Pachmanov</a></li> <li><!-- raw HTML omitted --> <a href="https://github.com/hainenber" title="+49/-4 ([#6539](axios/axios#6539) )">Đỗ Trọng Hải</a></li> </ul> <h2>Release v1.7.3</h2> <h2>Release notes:</h2> <h3>Bug Fixes</h3> <ul> <li><strong>adapter:</strong> fix progress event emitting; (<a href="https://redirect.github.com/axios/axios/issues/6518">#6518</a>) (<a href="https://github.com/axios/axios/commit/e3c76fc9bdd03aa4d98afaf211df943e2031453f">e3c76fc</a>)</li> <li><strong>fetch:</strong> fix withCredentials request config (<a href="https://redirect.github.com/axios/axios/issues/6505">#6505</a>) (<a href="https://github.com/axios/axios/commit/85d4d0ea0aae91082f04e303dec46510d1b4e787">85d4d0e</a>)</li> <li><strong>xhr:</strong> return original config on errors from XHR adapter (<a href="https://redirect.github.com/axios/axios/issues/6515">#6515</a>) (<a href="https://github.com/axios/axios/commit/8966ee7ea62ecbd6cfb39a905939bcdab5cf6388">8966ee7</a>)</li> </ul> <h3>Contributors to this release</h3> <ul> <li><!-- raw HTML omitted --> <a href="https://github.com/DigitalBrainJS" title="+211/-159 ([#6518](axios/axios#6518) [#6519](axios/axios#6519) )">Dmitriy Mozgovoy</a></li> <li><!-- raw HTML omitted --> <a href="https://github.com/ValeraS" title="+3/-3 ([#6515](axios/axios#6515) )">Valerii Sidorenko</a></li> <li><!-- raw HTML omitted --> <a href="https://github.com/prianyu" title="+2/-2 ([#6505](axios/axios#6505) )">prianYu</a></li> </ul> <h2>Release v1.7.2</h2> <h2>Release notes:</h2> <h3>Bug Fixes</h3> <ul> <li><strong>fetch:</strong> enhance fetch API detection; (<a href="https://redirect.github.com/axios/axios/issues/6413">#6413</a>) (<a href="https://github.com/axios/axios/commit/4f79aef81b7c4644328365bfc33acf0a9ef595bc">4f79aef</a>)</li> </ul> <h3>Contributors to this release</h3> <ul> <li><!-- raw HTML omitted --> <a href="https://github.com/DigitalBrainJS" title="+3/-3 ([#6413](axios/axios#6413) )">Dmitriy Mozgovoy</a></li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/axios/axios/blob/v1.x/CHANGELOG.md">axios's changelog</a>.</em></p> <blockquote> <h2><a href="https://github.com/axios/axios/compare/v1.7.3...v1.7.4">1.7.4</a> (2024-08-13)</h2> <h3>Bug Fixes</h3> <ul> <li><strong>sec:</strong> CVE-2024-39338 (<a href="https://redirect.github.com/axios/axios/issues/6539">#6539</a>) (<a href="https://redirect.github.com/axios/axios/issues/6543">#6543</a>) (<a href="https://github.com/axios/axios/commit/6b6b605eaf73852fb2dae033f1e786155959de3a">6b6b605</a>)</li> <li><strong>sec:</strong> disregard protocol-relative URL to remediate SSRF (<a href="https://redirect.github.com/axios/axios/issues/6539">#6539</a>) (<a href="https://github.com/axios/axios/commit/07a661a2a6b9092c4aa640dcc7f724ec5e65bdda">07a661a</a>)</li> </ul> <h3>Contributors to this release</h3> <ul> <li><!-- raw HTML omitted --> <a href="https://github.com/levpachmanov" title="+47/-11 ([#6543](axios/axios#6543) )">Lev Pachmanov</a></li> <li><!-- raw HTML omitted --> <a href="https://github.com/hainenber" title="+49/-4 ([#6539](axios/axios#6539) )">Đỗ Trọng Hải</a></li> </ul> <h2><a href="https://github.com/axios/axios/compare/v1.7.2...v1.7.3">1.7.3</a> (2024-08-01)</h2> <h3>Bug Fixes</h3> <ul> <li><strong>adapter:</strong> fix progress event emitting; (<a href="https://redirect.github.com/axios/axios/issues/6518">#6518</a>) (<a href="https://github.com/axios/axios/commit/e3c76fc9bdd03aa4d98afaf211df943e2031453f">e3c76fc</a>)</li> <li><strong>fetch:</strong> fix withCredentials request config (<a href="https://redirect.github.com/axios/axios/issues/6505">#6505</a>) (<a href="https://github.com/axios/axios/commit/85d4d0ea0aae91082f04e303dec46510d1b4e787">85d4d0e</a>)</li> <li><strong>xhr:</strong> return original config on errors from XHR adapter (<a href="https://redirect.github.com/axios/axios/issues/6515">#6515</a>) (<a href="https://github.com/axios/axios/commit/8966ee7ea62ecbd6cfb39a905939bcdab5cf6388">8966ee7</a>)</li> </ul> <h3>Contributors to this release</h3> <ul> <li><!-- raw HTML omitted --> <a href="https://github.com/DigitalBrainJS" title="+211/-159 ([#6518](axios/axios#6518) [#6519](axios/axios#6519) )">Dmitriy Mozgovoy</a></li> <li><!-- raw HTML omitted --> <a href="https://github.com/ValeraS" title="+3/-3 ([#6515](axios/axios#6515) )">Valerii Sidorenko</a></li> <li><!-- raw HTML omitted --> <a href="https://github.com/prianyu" title="+2/-2 ([#6505](axios/axios#6505) )">prianYu</a></li> </ul> <h2><a href="https://github.com/axios/axios/compare/v1.7.1...v1.7.2">1.7.2</a> (2024-05-21)</h2> <h3>Bug Fixes</h3> <ul> <li><strong>fetch:</strong> enhance fetch API detection; (<a href="https://redirect.github.com/axios/axios/issues/6413">#6413</a>) (<a href="https://github.com/axios/axios/commit/4f79aef81b7c4644328365bfc33acf0a9ef595bc">4f79aef</a>)</li> </ul> <h3>Contributors to this release</h3> <ul> <li><!-- raw HTML omitted --> <a href="https://github.com/DigitalBrainJS" title="+3/-3 ([#6413](axios/axios#6413) )">Dmitriy Mozgovoy</a></li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/axios/axios/commit/abd24a7367726616e60dfc04cb394b4be37cf597"><code>abd24a7</code></a> chore(release): v1.7.4 (<a href="https://redirect.github.com/axios/axios/issues/6544">#6544</a>)</li> <li><a href="https://github.com/axios/axios/commit/6b6b605eaf73852fb2dae033f1e786155959de3a"><code>6b6b605</code></a> fix(sec): CVE-2024-39338 (<a href="https://redirect.github.com/axios/axios/issues/6539">#6539</a>) (<a href="https://redirect.github.com/axios/axios/issues/6543">#6543</a>)</li> <li><a href="https://github.com/axios/axios/commit/07a661a2a6b9092c4aa640dcc7f724ec5e65bdda"><code>07a661a</code></a> fix(sec): disregard protocol-relative URL to remediate SSRF (<a href="https://redirect.github.com/axios/axios/issues/6539">#6539</a>)</li> <li><a href="https://github.com/axios/axios/commit/c6cce43cd94489f655f4488c5a50ecaf781c94f2"><code>c6cce43</code></a> chore(release): v1.7.3 (<a href="https://redirect.github.com/axios/axios/issues/6521">#6521</a>)</li> <li><a href="https://github.com/axios/axios/commit/e3c76fc9bdd03aa4d98afaf211df943e2031453f"><code>e3c76fc</code></a> fix(adapter): fix progress event emitting; (<a href="https://redirect.github.com/axios/axios/issues/6518">#6518</a>)</li> <li><a href="https://github.com/axios/axios/commit/85d4d0ea0aae91082f04e303dec46510d1b4e787"><code>85d4d0e</code></a> fix(fetch): fix withCredentials request config (<a href="https://redirect.github.com/axios/axios/issues/6505">#6505</a>)</li> <li><a href="https://github.com/axios/axios/commit/92cd8ed94362f929d3d0ed85ca84296c0ac8fd6d"><code>92cd8ed</code></a> chore(github): update ISSUE_TEMPLATE.md (<a href="https://redirect.github.com/axios/axios/issues/6519">#6519</a>)</li> <li><a href="https://github.com/axios/axios/commit/8966ee7ea62ecbd6cfb39a905939bcdab5cf6388"><code>8966ee7</code></a> fix(xhr): return original config on errors from XHR adapter (<a href="https://redirect.github.com/axios/axios/issues/6515">#6515</a>)</li> <li><a href="https://github.com/axios/axios/commit/0e4f9fa29077ebee4499facea6be1492b42e8a26"><code>0e4f9fa</code></a> chore(release): v1.7.2 (<a href="https://redirect.github.com/axios/axios/issues/6414">#6414</a>)</li> <li><a href="https://github.com/axios/axios/commit/4f79aef81b7c4644328365bfc33acf0a9ef595bc"><code>4f79aef</code></a> fix(fetch): enhance fetch API detection; (<a href="https://redirect.github.com/axios/axios/issues/6413">#6413</a>)</li> <li>See full diff in <a href="https://github.com/axios/axios/compare/v1.7.1...v1.7.4">compare view</a></li> </ul> </details> <br /> [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=axios&package-manager=npm_and_yarn&previous-version=1.7.1&new-version=1.7.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) You can trigger a rebase of this PR by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/facebook/react/network/alerts). </details> > **Note** > Automatic rebases have been disabled on this pull request as it has been open for over 30 days. Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
I am seeing something that looks like a bug and have written a simple test case for it.
Please refer to this WebpackBin as it contains the test scenario:
http://www.webpackbin.com/EJpabsuJW
The text was updated successfully, but these errors were encountered: