redux-saga-requests-react v0.3.0
redux-saga-requests-react
React bindings for Redux-Saga-Requests, Redux-Saga addon to simplify AJAX requests
Installation
To install the package, just run:
$ yarn add redux-saga-requests-reactor...
$ npm install redux-saga-requests-reactor you can just use CDN: https://unpkg.com/redux-saga-requests-react.
For general usage, see redux-saga-requests docs.
Purpose
This library is totally optional, but it reduces boilerplate of using react-saga-requests
state inside React components. It provides the following hooks and components:
useQuery
useQuery is a hook which uses useSelector from react-redux together with getQuerySelector from
redux-saga-requests. It accepts the same arguments as getQuerySelector. You could
easily use useSelector directly, but useQuery is slightly less verbose. So, without useQuery:
import React from 'react';
import { getQuerySelector } from 'redux-saga-requests';
import { useSelector } from 'react-redux';
const Books = () => {
const books = useSelector(getQuerySelector({ type: 'FETCH_BOOKS' }))
// ...
};and with useQuery:
import React from 'react';
import { useQuery } from 'redux-saga-requests-react';
const Books = () => {
const books = useQuery({ type: 'FETCH_BOOKS' })
// ...
};Query
Query simplifies rendering queries data, loading spinners and server errors. It automatically connects to Redux store
by using useQuery under the hood. It has the following props:
type: string: refer togetQueryform the core libraryselector: if you already have a query selector, pass it here instead oftypemultiple: refer togetQuerydefaultObject: refer togetQuerychildren- render function receivingqueryobject, called when data is not empty according toisDataEmptypropcomponent- alternative prop tochildren, you can pass your custom component here, which will receivequeryprop, plus any additional props passed toQueryisDataEmpty: query => boolean: function which defines whendatais empty, by default data as empty array and falsy value likenull,undefinedis considered as emptyshowLoaderDuringRefetch: boolean:trueby default, change it tofalseif you don't want to show spinner when data is updated - it will still show during initial fetch, but will not for subsequent requestsnoDataMessage:stringor any React node, like<div>message</div>, which will be rendered whendatais empty according toisDataEmptyfunction,nullby defaulterrorComponent: custom React component, which will be rendered on error, receiveserrorprop,nullby defaulterrorComponentProps: object of additional props passed toerrorComponentloadingComponentcustom React component, which will be rendered when request is pending, useful for showing spinners,nullby defaultloadingComponentProps: object of additional props passed toloadingComponent
Minimalistic example:
import { Query } from 'redux-saga-requests-react';
<Query
type={REQUEST_TYPE}
// or selector={myQuerySelector}
>
{({ data }) => (
<div>
{data}
</div>
)}
</Query>or with component prop:
import { Query } from 'redux-saga-requests-react';
const DataComponent = ({ query, extraLabelProp }) => (
<div>
<h1>{extraLabelProp}</h1>
{query.data}
</div>
);
<Query
type={REQUEST_TYPE}
// or selector={myQuerySelector}
component={DataComponent}
extraLabelProp="label"
/>or with all props:
import { Query } from 'redux-saga-requests-react';
const LoadingComponent = ({ label }) => (
<div>
...loading
{label}
</div>
);
const ErrorComponent = ({ error, label }) => (
<div>
Error with status code {error.status}
{label}
</div>
);
<Query
type={REQUEST_TYPE}
// or selector={myQuerySelector}
isDataEmpty={query =>
Array.isArray(query.data) ? query.data.length === 0 : !query.data}
showLoaderDuringRefetch={false}
noDataMessage="There is no data"
errorComponent={ErrorComponent}
errorComponentProps={{ label: 'Error label' }}
loadingComponent={LoadingComponent}
loadingComponentProps={{ label: 'Loading label' }}
>
{({ data }) => (
<div>
{data}
</div>
)}
</Query>useMutation
useMutation is a hook which uses useSelector from react-redux together with getMutationSelector from
redux-saga-requests. It accepts the same arguments as getMutation. Like in case of useQuery, you could
easily use useSelector directly, but then you would need to remember not to recreate selector during each
render.
For example:
import React from 'react';
import { useMutation } from 'redux-saga-requests-react';
const Books = () => {
const { loading, error } = useMutation({ type: 'DELETE_BOOK' })
// ...
};Mutation
Mutation Converts useMutation into component with render prop. It has the following props:
type: string: refer touseMutationselector: if you already have a mutation selector, pass it here instead oftyperequestKey: string: refer touseMutationchildren- render function receiving object withloadingflag anderrorpropertycomponent- alternative prop tochildren, you can pass your custom component here, which will receiveloadinganderrorprops, plus any additional props passed toMutation
You use it like this:
import { Mutation } from 'redux-saga-requests-react';
<Mutation
type={MUTATION_TYPE}
// or selector={myMutationSelector}
>
{({ loading, error }) => {
if (error) {
return <div>Something went wrong</div>;
}
return (
<button onClick={dispatchSomeMutation} disabled={loading}>
Send mutation {loading && '...' }
</button>
);
}}
</Mutation>Licence
MIT