Skip to content

v2.0.0

Compare
Choose a tag to compare
@BenLorantfy BenLorantfy released this 30 May 02:00
· 5 commits to master since this release
ff48adf

It’s been a long time coming, but redux-injectors 2.0 is here 🎉

This release contains some breaking changes and some new features. Unfortunately some breaking changes were needed in order to fix #19 .

For the announcement blog post, see this link.

💥 Breaking Changes

useInjectReducer

  • Reducer injection now happens inside a useLayoutEffect instead of during the render. This means the following patterns will be broken:
    • A useSelector call after a call to useInjectReducer will result in undefined for the first render, if the selector tries to select from a piece of state that the reducer manages. If you need to do this, please make your selector resilient to undefined state.
    • An injected reducer will not receive a dispatch if that dispatch is made inside a useLayoutEffect inside a component further down the tree. This can be fixed by any of the following:
      • Use useEffect instead of useLayoutEffect
      • useInjectReducer now returns a boolean indicating whether or not the reducer has finished injecting. This allows you to return null if the boolean is false instead of the component's children.
      • Use the new createManager API which does the above point for you

useInjectSaga

  • Saga injection now happens inside a useLayoutEffect instead of during the render. This means the saga will not catch a dispatch made inside a useLayoutEffect inside a component further down the tree. This can be fixed in the same ways as explained in the useInjectReducer section
  • The default saga injection mode was changed to COUNTER. In this mode, the saga will be injected once at-least 1 component mounts that depends on this saga. The saga will be ejected once every component that depends on this saga un-mounts. This means multiple components can inject the saga, but the saga will only run once until every one of these components un-mounts.
  • The mode parameter for useInjectSaga was removed. The default and only possible mode for saga injection is now COUNTER.

🚀 New Features

createManager

This is a new API that creates a "manager" component given a reducer and/or saga. Each manager will only render its children after both
the reducer and saga has been injected. You can almost think of managers like "providers" for reducers and sagas.

const BooksManager = createManager({ name: "BooksManager", key: "books", reducer: booksReducer, saga: booksSaga })

...

<BooksManager>
  <BooksList />
</BooksManager>

This is now the recommended way to use redux-injectors because it avoids some caveats with useInjectReducer and useInjectSaga.

COUNTER mode

The COUNTER mode is a new saga injection mode, and the only mode used by useInjectSaga. This mode is relevant when multiple useInjectSaga are injecting the same saga. When the first useInjectSaga injects, the saga will be run. Each subsequent useInjectSaga will not re-run the saga. The saga will be ejected when the last component using the saga un-mounts.

In other words, this means multiple components can inject the saga, but the saga will only run once until every one of these components un-mounts. Thanks @goranurukalo for the contribution!

📝 Documentation

  • A note was added to the documentation recommending to set shouldHotReload: false for redux dev tools.
  • An example app was added