Skip to content
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

[v7-beta] Add test for dynamically injecting reducers #1211

Merged
merged 1 commit into from
Mar 22, 2019

Conversation

Ephem
Copy link
Contributor

@Ephem Ephem commented Mar 22, 2019

As asked for in #1177, this PR contains a new integration test-file dynamic-reducers.spec.js with an implementation for dynamically injecting reducers during the render phase with one test for the client and one for the server.

Right now it only tests the basic expectation that the wrapped child renders with the initial state from the dynamically injected reducer, this seemed most valuable to me to start with, but can be easily expanded upon. With more tests and tweaks, I guess this implementation could grow/morph to become some form of semi-documented best practice for dynamic reducer injection as long as no public APIs exists.

The reason we do this as a side effect in the render phase is to support SSR, see the comment in the test file for slightly more details. redux-dynamic-modules does something similar to this, but executes the side effect in construct instead, I tried to simplify by placing all logic in render. Instead of relying on the constructor only running once, this has guards to determine when injection and possible patching of storeState needs to happen or not during rendering.

By only patching storeState if it exists and otherwise relying on connected child components to fetch an updated state themselves, this test works both with v6 and the current v7-beta.

Do note that this is a pretty fragile test that relies on internal and undocumented implementation details of Redux (and probably React), but as @markerikson pointed out, it's hopefully better than nothing. 🤷‍♂️

I am very open to feedback on how to improve this further, besides from maintainers, I would love feedback from @abettadapur and @mpeyper 😄

@netlify
Copy link

netlify bot commented Mar 22, 2019

Deploy preview for react-redux-docs ready!

Built with commit 7648588

https://deploy-preview-1211--react-redux-docs.netlify.com

test/run-tests.js Outdated Show resolved Hide resolved
getByText('Hello world')
getByText('Hello dynamic world')
})
it('should render child with initial state on the server', () => {
Copy link
Contributor Author

@Ephem Ephem Mar 22, 2019

Choose a reason for hiding this comment

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

Sadly the test-environment can only differ between files, not single tests. If you think it makes more sense, I'll refactor the implementation into a util-file and move this test over to the SSR-suite where the true node test-environment is running, or a new dynamic-reducers-server.spec.js.

@timdorr
Copy link
Member

timdorr commented Mar 22, 2019

Can we base this on the v7-beta branch instead?

@Ephem Ephem changed the base branch from master to v7-beta March 22, 2019 15:45
@Ephem
Copy link
Contributor Author

Ephem commented Mar 22, 2019

Done! I suspected you might want that so I had it prepared. 😄

@Ephem Ephem changed the title Added test for injecting dynamic reducers on client and server [v7-beta] Add test for dynamically injecting reducers Mar 22, 2019
@timdorr
Copy link
Member

timdorr commented Mar 22, 2019

Perfect. Thanks!

@timdorr timdorr merged commit 79982c9 into reduxjs:v7-beta Mar 22, 2019
markerikson pushed a commit that referenced this pull request Apr 9, 2019
* Update React to latest

* Update React peer dependency to 16.8.x

* Initial re-implementation of `connectAdvanced` using hooks

Matches changes from v7.0.0-alpha.1

* Update tests to match v7-alpha.1 behavior

Added rtl.act() calls around dispatches and other component updates
Added clarification on expected mapState calls in some places
Disabled some no-longer-relevant tests per implementation
Made tests run against React 16.8 by default

* adding a react hooks test that fails with v7 alpha

* wrapping store.dispatch with rlt.act, fixes component renders

* reducing hooks test to 2 components

* Fix case where wrapper props changed before store update render

* Mark ReactDOM as global in UMD builds

Matches state as of v7.0.0-alpha.2

* Fix perf problems with out-of-bounds array access

Matches state as of v7.0.0-alpha.3

* Add modules to handle importing batchedUpdates

* Use appropriate batched update API for subscriptions

* Inject unstable_batchedUpdates in default entry point

* Provide an alternate entry point for alternate renderers

Matches state as of v7.0.0-alpha.4

* Remove batch arg from createListenerCollection (#1205)

This prevents a bug with Terser (webpack's default minifier) where the
returned batch function isn't defined due to function inlining.

Matches state as of v7.0.0-alpha.5

* Remove older React versions from Travis

* Add comments to connectAdvanced. Many much comments!

* Re-add test for a custom store as a prop

* Fix null pointer exception when store is given as a prop

We were trying to read contextValue.subscription, even if that
value was null.  Reworked logic to handle cases where the store
came in as a prop.

* Ensure wrapper props are passed correctly when forwarding refs

* Add a test to verify subscription passthrough with store-as-prop

* add non-batched tests (#1208)

* Force SSR tests to mimic a Node environment

* Restructure connect tests to group by category for easier reading

Yeah, this kills the blame history. Sorry. But it's a lot easier
to figure out what the tests are used for now.

* Clean up dead code in Provider tests

* Add tests to verify errors are thrown for bad mapState functions

* Fix edge cases around saved wrapper props and error handling

Changed to useLayoutEffect to ensure that the lastWrapperProps ref
is written to synchronously when a render is committed. However,
because React warns about this in SSR, added a check to fall back
to plain useEffect under Node so we don't print warnings.

Also added logic to ensure that if an error is thrown during a
mapState function, but the component is unmounted before it can
render, that the error will still be thrown.  This shouldn't happen
given our top-down subscriptions, but this will help surface the
problem in our tests if we ever break the top-down behavior.

* Formatting

* Add a test to verify no errors are printed in SSR usage

* Ignore .idea/

* 7.0.0-beta.0

* Updated outdated SSR-test (dispatch in ancestors) (#1213)

* Added test for injecting dynamic reducers on client and server (#1211)

* Remove WebStorm gitignore

This goes in a global gitignore file, not a project.

* [FIX]: #1219 Save references before update (#1220)

* Re-ignore .idea/

* 7.0.0-beta.1

* Update the codecov config to be more forgiving.

* add test to verify that mapStateToProps is always called with latest store state (#1215)
webguru7 pushed a commit to webguru7/react-redux that referenced this pull request Dec 8, 2022
* Update React to latest

* Update React peer dependency to 16.8.x

* Initial re-implementation of `connectAdvanced` using hooks

Matches changes from v7.0.0-alpha.1

* Update tests to match v7-alpha.1 behavior

Added rtl.act() calls around dispatches and other component updates
Added clarification on expected mapState calls in some places
Disabled some no-longer-relevant tests per implementation
Made tests run against React 16.8 by default

* adding a react hooks test that fails with v7 alpha

* wrapping store.dispatch with rlt.act, fixes component renders

* reducing hooks test to 2 components

* Fix case where wrapper props changed before store update render

* Mark ReactDOM as global in UMD builds

Matches state as of v7.0.0-alpha.2

* Fix perf problems with out-of-bounds array access

Matches state as of v7.0.0-alpha.3

* Add modules to handle importing batchedUpdates

* Use appropriate batched update API for subscriptions

* Inject unstable_batchedUpdates in default entry point

* Provide an alternate entry point for alternate renderers

Matches state as of v7.0.0-alpha.4

* Remove batch arg from createListenerCollection (reduxjs#1205)

This prevents a bug with Terser (webpack's default minifier) where the
returned batch function isn't defined due to function inlining.

Matches state as of v7.0.0-alpha.5

* Remove older React versions from Travis

* Add comments to connectAdvanced. Many much comments!

* Re-add test for a custom store as a prop

* Fix null pointer exception when store is given as a prop

We were trying to read contextValue.subscription, even if that
value was null.  Reworked logic to handle cases where the store
came in as a prop.

* Ensure wrapper props are passed correctly when forwarding refs

* Add a test to verify subscription passthrough with store-as-prop

* add non-batched tests (reduxjs#1208)

* Force SSR tests to mimic a Node environment

* Restructure connect tests to group by category for easier reading

Yeah, this kills the blame history. Sorry. But it's a lot easier
to figure out what the tests are used for now.

* Clean up dead code in Provider tests

* Add tests to verify errors are thrown for bad mapState functions

* Fix edge cases around saved wrapper props and error handling

Changed to useLayoutEffect to ensure that the lastWrapperProps ref
is written to synchronously when a render is committed. However,
because React warns about this in SSR, added a check to fall back
to plain useEffect under Node so we don't print warnings.

Also added logic to ensure that if an error is thrown during a
mapState function, but the component is unmounted before it can
render, that the error will still be thrown.  This shouldn't happen
given our top-down subscriptions, but this will help surface the
problem in our tests if we ever break the top-down behavior.

* Formatting

* Add a test to verify no errors are printed in SSR usage

* Ignore .idea/

* 7.0.0-beta.0

* Updated outdated SSR-test (dispatch in ancestors) (reduxjs#1213)

* Added test for injecting dynamic reducers on client and server (reduxjs#1211)

* Remove WebStorm gitignore

This goes in a global gitignore file, not a project.

* [FIX]: reduxjs#1219 Save references before update (reduxjs#1220)

* Re-ignore .idea/

* 7.0.0-beta.1

* Update the codecov config to be more forgiving.

* add test to verify that mapStateToProps is always called with latest store state (reduxjs#1215)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants