Giter Site home page Giter Site logo

Comments (10)

philipp-spiess avatar philipp-spiess commented on June 10, 2024

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.

stereobooster avatar stereobooster commented on June 10, 2024

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.

philipp-spiess avatar philipp-spiess commented on June 10, 2024

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.

stereobooster avatar stereobooster commented on June 10, 2024

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.

philipp-spiess avatar philipp-spiess commented on June 10, 2024

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.

stereobooster avatar stereobooster commented on June 10, 2024

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.

philipp-spiess avatar philipp-spiess commented on June 10, 2024

@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.

stereobooster avatar stereobooster commented on June 10, 2024

(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.

philipp-spiess avatar philipp-spiess commented on June 10, 2024

Thanks for all the infos! I'll reopen this ticket then 🙂

from react-recomponent.

stereobooster avatar stereobooster commented on June 10, 2024

Just an idea https://github.com/stereobooster/use-redux-loop/blob/master/src/useReduxLoop.js

from react-recomponent.

Related Issues (10)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.