Comments (10)
Hey @stereobooster 🙌 Thanks for checking out react-recomponent and getting this discussion started.
The Cmd
module of redux-loop
is definitely interesting although I don't think it is very intuitive what's going on (I have re-read the same text a few times and still feel like I don't fully get it 😐). It seems like it solves the testability of side-effects that cause other actions to dispatch (in your example the success and fail actions).
When building react-recomponent I thought a lot about testability as well. I've worked with redux-thunk a long time and know that simply returning functions can be though as you have to run the function and mock away all side effects in order to verify it behaves correctly (exactly as you've said).
Since a reducer component is also a React component I think that the reducer might not necessarily need to be tested as a standalone unit but together with the component's behavior in either a shallow or a full render. If you look into the tests you'll see that we're always using a full ReactDOM.render()
to set up the example and only test using public API. This is of course only possible because the complexity of the application allows it. I've used shallow rendering in cases where this is not feasible (e.g. at PSPDFKit we can't afford to mount our PDF engine for every unit test (yet)).
I guess my point is that I recommend testing at a higher level of abstraction. And yes, this will mean that there's no way around mocking but it is also the only way to make sure that the function you mock is really called with the properties you're expecting and avoids certain abstractions in the reducer itself.
I'm going to close this ticket since it's nothing actionable but we can keep discussing this - I would love to hear your thoughts on this. 🙂
from react-recomponent.
Since a reducer component is also a React component I think that the reducer might not necessarily need to be tested as a standalone unit but together with the component's behavior in either a shallow or a full render.
This is an option. My thought was - because this is static property and it is supposed to be pure, it will be easier to test it directly instead of dealing with component rendering.
My initial idea was to give it a try instead of Redux. So I expect a pretty beefy reducer there and coupling with the component itself can be hard.
from react-recomponent.
I see what you mean! I don't think a reducer component is a good replacement for a global state redux application though - There is really no need to combine the state with a component in those cases. Although it is perfectly fine to use react-recomponent with a specific subtree and pass props along as they are needed. I think that in those cases mocking (e.g. jest.mock("fetchData");
) should work fine.
from react-recomponent.
I see what you mean! I don't think a reducer component is a good replacement for a global state redux application though. There is really no need to combine the state with a component in those cases
If I would use reComponent as renderless component - this is basically Redux. Isn't it? Except it doesn't have handy middlewares like dev tools, but this is not the point here.
from react-recomponent.
Yes that's correct. I haven't used it that way though but I don't think it would be a problem - You can use Context
to pass the props down to where they are needed and you can even build an API similar to Redux's connect()
I suppose. 🙂
from react-recomponent.
Hey! It's me again. I wrote the post about Redux-loop and how it is easy to test it https://github.com/stereobooster/react-fsm-example/tree/post-2.
I can test all logic without touching actual side effects https://github.com/stereobooster/react-fsm-example/blob/post-2/src/redux-fsm/reducers.test.js and I can test side effect separately. WDYT?
from react-recomponent.
@stereobooster Thanks for following up. This type of test seems useful. Be aware that you're still mocking the side effect to return { success: true, result: "response" }
in this case (It's not clear to me how this is returned, maybe a Promise?) but if you control that API and can make sure the side effect returns this format, this might be ok.
In order to implement this in ReComponent we'd need the ability to provide a middleware function I suppose. So that a Cmd.run()
object can be executed immediately in production mode but won't execute in dev mode. We'd then be able to do the same thing:
const { state: nextState, sideEffect } = reducer(action, state);
expect(sideEffect.simulate({ success: true, result: 123 })).toEqual({
response: "response",
type: "SUBMIT_FRUIT_OK"
});
So maybe we should make it easy to register middleware functions. Do you think this would be helpful? In this case it should be possible to use Cmd
from Redux-loop.
from react-recomponent.
(It's not clear to me how this is returned, maybe a Promise?)
Cmd.run(fruitRequest, {
successActionCreator: resonse => { ... },
failActionCreator: error => { ... },
})
If fruitRequest
returns promise, than successActionCreator
will be executed for promise.than
and failActionCreator
for promise.catch
If fruitRequest
doesn't return a promise, than successActionCreator
will be executed for any return value, and failActionCreator
will be executed if fruitRequest
throws exception.
sideEffect.simulate({ success: true, result: ... })
will always call successActionCreator
sideEffect.simulate({ success: false, result: ... })
will always call failActionCreator
So maybe we should make it easy to register middleware functions. Do you think this would be helpful?
I guess yes 🤔
from react-recomponent.
Thanks for all the infos! I'll reopen this ticket then 🙂
from react-recomponent.
Just an idea https://github.com/stereobooster/use-redux-loop/blob/master/src/useReduxLoop.js
from react-recomponent.
Related Issues (10)
- TypeScript Definitions HOT 8
- Make reducer an instance method instead of a static method HOT 2
- Could not find a declaration file for module 'react-recomponent' HOT 5
- Static reducer TypeScript annotations HOT 7
- Hosted link not working HOT 1
- Enforce purity of reduce method by converting it to static HOT 6
- Example Apps HOT 2
- Improve Flow Coverage
- First class Flow support HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-recomponent.