A redux middleware that lets you use your own data fetching and expose the results in a suspense compatible way
A redux middleware that lets you use your own data fetching and expose the results in a suspense compatible way
npm install redux-suspense
Add the reducer
// src/reducers/index.js
import { combineReducers } from 'redux'
import { suspenseReducer } from 'redux-suspense'
const rootReducer = combineReducers({
// ...your other reducers here
// you have to pass suspenseReducer under 'suspense' key,
suspense: suspenseReducer
})
import { createStore, applyMiddleware } from 'redux';
import { suspenseMiddleware } from 'redux-suspense';
import rootReducer from 'src/reducers/index';
const store = createStore(rootReducer, applyMiddleware(suspenseMiddleware));
// src/resources/postsResources.js
import { createResource } from 'redux-suspense';
export const postsResource = createResource(
'POSTS',
fetchPosts, // this is your async function that fetches and returns the posts
)
If you want to store the posts in your own reducer just pass a selector to createResource
. For example:
export const postsResource = createResource(
'POSTS',
fetchPosts,
state => state.yourPostsReducer.posts
)
// Then you can export the success action to handle it in your reducer.
export const { success: fetchPostsSuccess } = postsResource
createResource
will create a couple more things:
resourceName
This is the same string you passed as first argument.handler
The function you passed as the second argument.success
, error
and request
These are action creators. All of which have a toString()
method. In the example above succes.toString()
would evaluate to 'POSTS_SUCCESS'
selector
The selector you passed as the third argument.Dispatch the resource as an action, as soon as you want to start fetching data. And use useResource
as if it was a selector, inside a <Suspense>
tag.
import React, { Suspense, useEffect } from 'react'
import { useDispatch } from 'react-redux'
import { postsResource } from 'src/resources/postsResources.js'
function App () {
const dispatch = useDispatch()
useEffect(() => dispatch(postsResource), [])
return (
<Suspense fallback={<h1> Loading...</h1>}>
<Posts ></Posts>
</Suspense>
)
}
import { useResource } from 'redux-suspense'
import { postsResource } from 'src/resources/postsResources.js'
export function Posts() {
const posts = useResource(postsResource)
return (
<div>
{posts}
</div>
)
}
We use SemVer for versioning. For the versions available, see the tags on this repository.
This project is licensed under the ISC License - see the LICENSE file for details