Library that allows you to integrate your React app into a backend with ease.
Core features:
- Define requests once and use anywhere
- Keeps track of request state (loading, error, result)
- Allows mapping request state to React components
npm i react-with-requests
First, we define which requests our app can make.
// requests.js
import { Request } from 'react-with-requests';
export const fetchProducts = new Request({
// how the product should be fetched
request: async () => {
const response = await fetch(`example.com/products`);
return await response.json();
},
defaultMapping: {
// which prop will hold status of the request
statusProp: 'products',
// which prop acts as a function to execute request
requestProp: 'fetchProducts',
},
})
export const fetchShop = new Request({
request: async (id) => {
const response = await fetch(`example.com/shops/${id}`);
return await response.json();
},
defaultMapping: {
statusProp: 'shop',
requestProp: 'fetchShop',
},
});
This library uses Reacts new Context API. Therefore, we should add Provider on the top of our component tree so that our components can consume state from the RequestStateHandler that actually handles lifecycle of the requests.
// App.js
import React from 'react';
import { Provider } from 'react-with-requests';
class App extends React.Component {
render() {
return (
<Provider>
// Render your apps component tree here
</Provider>
);
}
}
Now, for the interesting part. How to map requests to components?
You can do this with either render props (using RequestStateConsumer component) or HOC (using withRequests utility). Lets look at the HOC approach first, as that might be simpler for at least people coming from Redux world.
// Shop.js
import React from 'react';
import { withRequests } from 'react-with-requests';
import { fetchProducts, fetchShop } from './requests';
// select which requests this component should depend on
const requests = (props) => ([
fetchProducts,
// define that shop's id should depend on components id prop
fetchShop.withParams(props.id)
]);
const Shop = ({ shop, products, fetchProducts }) => (
// shop and products are statusProps, which contain:
// - result (any)
// - error (any)
// - loading (boolean)
<div>
{
// when accessing result properties make sure
// that result is actually available
shop.result && <h1>{shop.result.name}</h1>
}
{
products.result && products.result.map(product => (
<div className="card">
<img src={product.image}/>
<span>{product.name}</span>
</div>
))
}
</div>
)
// remember to map request state to the actual component
export default withRequests(requests)(ProductPage);
Coming soon?