Skip to content
This repository has been archived by the owner on Aug 26, 2022. It is now read-only.

Extract duplicate switch statement into component #6658

Merged
merged 2 commits into from
Mar 19, 2020

Conversation

erkde
Copy link
Contributor

@erkde erkde commented Mar 8, 2020

This commit just extracts the duplicate switch statement in index.jsx and ssr.jsx into it’s own thing, an App component.

As the default handling for an unknown prop componentName is different in index.jsx (throws an error) than in ssr.jsx (writes to console), the App component just returns null to indicate this condition.

App also takes an optional second prop data, in index.jsx it comes from window._react_data, I can’t find a type for it anywhere, so have left it as any for now.

@erkde erkde force-pushed the refactor-duplicate-switch-into-app branch from 447f44d to 8669539 Compare March 8, 2020 22:49
@codecov-io
Copy link

codecov-io commented Mar 8, 2020

Codecov Report

Merging #6658 into master will increase coverage by 0.03%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #6658      +/-   ##
==========================================
+ Coverage   95.75%   95.79%   +0.03%     
==========================================
  Files         294      294              
  Lines       26384    26321      -63     
  Branches     2018     2015       -3     
==========================================
- Hits        25265    25215      -50     
+ Misses        875      863      -12     
+ Partials      244      243       -1
Impacted Files Coverage Δ
kuma/users/checks.py 41.17% <0%> (-0.93%) ⬇️
kuma/payments/views.py 95.23% <0%> (-0.32%) ⬇️
kuma/users/tasks.py 100% <0%> (ø) ⬆️
kuma/payments/tests/test_views.py 100% <0%> (ø) ⬆️
kuma/users/tests/test_stripe_subscription.py 100% <0%> (ø) ⬆️
kuma/settings/common.py 84.51% <0%> (ø) ⬆️
kuma/api/v1/tests/test_views.py 100% <0%> (ø) ⬆️
kuma/users/stripe_utils.py
kuma/users/utils.py 31.03% <0%> (ø)
kuma/users/views.py 94.19% <0%> (+1%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 1692886...acba1e0. Read the comment docs.

@peterbe peterbe requested a review from Gregoor March 9, 2020 14:54
@peterbe
Copy link
Contributor

peterbe commented Mar 9, 2020

@Gregoor Can you take a look at this. I know you mentioned something similar and perhaps you can better visualize what's going on with on-going open pull requests that would conflict with this.

Copy link
Contributor

@Gregoor Gregoor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for starting to tackle this. I don't think we're quite there yet, but it's close!

);
let app = <App componentName={componentName} data={data} />;

if (app === null) {
Copy link
Contributor

@Gregoor Gregoor Mar 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React.createElement for which JSX is syntactical sugar always returns an object, describing the component to be rendered (and its props). What will be null is the renderer output. E.g.:
Screenshot (2)

So the app === null checks in both components would always be false, hence this is a functional changes that prevents errors from being logged / thrown.

One workaround would be to let the component itself throw and then add an error boundary for the SSR component. It'd also be great if we had tests that made sure it's correctly catching and logging the error in that case then.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Gregoor thanks for spotting this, and the comments.

I've just added a second commit c878df1 so it throws, along with a test to check ssr.jsx writes the caught error to console.

With adding an error boundary to the SSR component, I notice in index.jsx - the throw happens outside of the AppErrorBoundary, as it did before with the switch statement, I guess this is intentional, or should it actually be inside?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I think my comment above is partially incorrect, it seems in index.jsx, the error is not thrown when the App component is assigned, e.g.

let app = <App componentName={componentName} data={data} />;

or when it is re-assigned to within the AppErrorBoundary, e.g.

let app = (
  <GAProvider>
    <AppErrorBoundary>
      <React.StrictMode>{app}</React.StrictMode>
    </AppErrorBoundary>
  </GAProvider>
);

but when app is passed to render, e.g.

ReactDOM.render(app, container);

So, I guess this PR's moves the error from being thrown outside of the AppErrorBoundary, to inside.

I'm not sure I understand why you would want to throw the error outside of it, but this does seem to change that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more thing, using error boundaries in ssr.jsx, doesn't seem to be currently supported with renderToString: facebook/react#10442

@erkde erkde force-pushed the refactor-duplicate-switch-into-app branch from 41b764c to c878df1 Compare March 9, 2020 22:00
@erkde
Copy link
Contributor Author

erkde commented Mar 9, 2020

Note - has additional commit(s) based on review, may need a squash/edit.

@erkde erkde requested a review from Gregoor March 12, 2020 05:52
This commit just extracts the duplicate switch statement in index.jsx
and ssr.jsx into it’s own thing, an App component.

As the default handling for an unknown prop `componentName` is different 
in index.jsx (throws an error) than in ssr.jsx (writes to console), the 
App component just returns null to indicate this condition. 

App also takes an optional second prop `data`, in index.jsx it comes
from `window._react_data`, I can’t find a type for it anywhere, so have 
left it as `any` for now.
@erkde erkde force-pushed the refactor-duplicate-switch-into-app branch from c878df1 to acba1e0 Compare March 18, 2020 20:34
Fixup for commit 8669539 changing the App component to throw an Error
when passed an invalid or unknown `componentName` prop, allowing 
index.jsx and ssr.jsx to handle appropriately.
@erkde erkde force-pushed the refactor-duplicate-switch-into-app branch from acba1e0 to 29182a6 Compare March 18, 2020 20:56
@Gregoor
Copy link
Contributor

Gregoor commented Mar 19, 2020

Sorry for taking so long to get back to you and thanks for making the changes and adding tests!

I would've had one more nit, which is the fact that we're checking for the error message, instead of introducing a new error type. Then I learned that babel doesn't properly subclass and became sad. But now we have tests, so at least a mindless change to the error message blows CI up. So I guess we're good on that front :)

Regarding your notes:
Fortunately we don't rely on error boundaries in SSR atm, so as long as renderToString throws (which it does), we're good. And with index.jsx (aka the client bootstrap) the error throwing happens within the boundary (as we noticed before on-render, not on-create-element), so we can still control what users see as well as report the error to our analytics.

Thanks again for the patience with me and with Kuma (I just needed some time to figure out how to re-run the SSR piece myself, so double kudos for you).

@Gregoor Gregoor merged commit 86b474e into mdn:master Mar 19, 2020
@Gregoor
Copy link
Contributor

Gregoor commented Mar 19, 2020

Oh an if you want to look at another consolidation task (though more Python-heavy), here's one: #6678

@erkde erkde deleted the refactor-duplicate-switch-into-app branch March 19, 2020 23:12
@erkde
Copy link
Contributor Author

erkde commented Mar 20, 2020

Cool, thanks @Gregoor - happy to take a squiz at #6678

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants