diff --git a/README.md b/README.md index 6e0fc9c..8b3d4f4 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@

React http fetch

- react-http-fetch logo + react-http-fetch logo
A http library for React JS built on top of JS native fetch.
@@ -44,6 +44,12 @@ Just follow links below to get an overview of library features. - [Example – Abortable request](#example--abortable-request) - [Example – Get request](#example--get-request) - [Request hooks](#request-hooks) + - [Http request hook params](#http-request-hook-params) + - [Http request hook return](#http-request-hook-return) + - [Http request state](#http-request-state) + - [Example – Http request hook triggered automatically on component mount](#example--http-request-hook-triggered-automatically-on-component-mount) + - [Example – Http request hook triggered manually on component mount](#example--http-request-hook-triggered-manually-on-component-mount) + - [Example – Http post request hook](#example--http-post-request-hook) - [Events](#events) - [Caching](#caching) - [Browser support](#browser-support) @@ -65,7 +71,7 @@ yarn add react-http-fetch ``` ## Provider -You can override the default configuration used by the http client to peform any request by using the `HttpClientConfigProvider`: +You can override the default configuration used by the http client to perform any request by using the `HttpClientConfigProvider`: ```js import { defaultHttpReqConfig, HttpClientConfigProvider } from 'react-http-fetch'; @@ -279,10 +285,115 @@ export default App;
## Request hooks +The library provides a hook `useHttpRequest` managing the state of the http request. Such state is returned by the hook along with a function to trigger the request. See [params](#http-request-hook-params) and [return](#http-request-hook-return) for more info. A dedicated hook is provided for every http method: `useHttpGet`, `useHttpPost`, `useHttpPatch`, `useHttpPut`, `useHttpDelete`. + +### Http request hook params +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| baseUrlOverride | string | The base url of the request. If provided, it would override the [provider](#provider) base url. +| relativeUrl | string | The url relative to the base one (e.g. posts/1). +| parser | [HttpResponseParser](src/client/types.ts) | An optional response parser that would override the [provider](#provider) global one. | +| requestOptions | [HttpRequestOptions](./src/client/types.ts) | The options carried by the fetch request. | +| initialData | any | The value that the state assumes initially before the request is send. | +| fetchOnBootstrap | boolean | Tell if the fetch must be triggered automatically when mounting the component or not. In the second case we would like to have a manual fetch, this is optained by a request function returned by the hook. | + +### Http request hook return +Returns an array of two elements, the first one embeds the state of the http request and the second one is a function that can be used to trigger the http request. The table below describes the shape (i.e. properties) of http request state. + +### Http request state +| Property | Type | Description | +| --------- | ---- | ----------- | +| pristine | boolean | Tells if the request has been dispatched. | +| errored | boolean | Tells if the request has returned an error. | +| isLoading | boolean | Tells if the request is pending. | +| error | unknown | property evaluated by the error generated by the backend api. | +| data | any | The response provided by the backend api. | + +### Example – Http request hook triggered automatically on component mount +```js +import { useHttpRequest } from 'react-http-fetch'; + +function App() { + const [state] = useHttpRequest({ + baseUrlOverride: 'https://jsonplaceholder.typicode.com', + relativeUrl: 'todos/1', + requestOptions: {}, + initialData: {}, + fetchOnBootstrap: true, + }); + + return ( +

{`Todo name: ${state && state.data && state.data.title}`}
+ ); +} + +export default App; +``` + +
+ +### Example – Http request hook triggered manually on component mount +```js +import { useHttpRequest } from 'react-http-fetch'; +import { useEffect } from 'react'; + +function App() { + const [state, request] = useHttpRequest({ + baseUrlOverride: 'https://jsonplaceholder.typicode.com', + relativeUrl: 'todos/1', + }); + + useEffect(() => request(), [request]); + + return ( +
{`Todo name: ${state && state.data && state.data.title}`}
+ ); +} + +export default App; +``` + +### Example – Http post request hook
## Events +Every time a request is executed the events shown below will be emitted. Each event carries a specific payload. + +| Event type | Payload type | +| --------- | ---- | +| [RequestStartedEvent](src/events-manager/events/request-started-event.ts) | [HttpRequest](src/client/http-request.ts) | +| [RequestErroredEvent](src/events-manager/events/request-errored-event.ts) | [HttpError](src/errors/http-error.ts) | +| [RequestSuccededEvent](src/events-manager/events/request-succeded-event.ts) |[RequestSuccededEventPayload](src/events-manager/events/request-succeded-event.ts) | + +It's possible to subscribe a specific event using the [useHttpEvent](src/events-manager/use-http-event.ts) hook as shown below: + +```js +import { useState } from 'react'; +import { RequestErroredEvent, RequestStartedEvent, RequestSuccededEvent, useHttpEvent, useHttpRequest } from 'react-http-fetch'; + +function App() { + const [count, setCount] = useState(0); + + const [, request] = useHttpRequest({ + baseUrlOverride: 'https://jsonplaceholder.typicode.com', + relativeUrl: 'todos/1', + }); + + useHttpEvent(RequestStartedEvent, () => setCount(count + 1)); + useHttpEvent(RequestSuccededEvent, () => setCount(count > 0 ? count - 1 : 0)); + useHttpEvent(RequestErroredEvent, () => setCount(count > 0 ? count - 1 : 0)); + + return ( + <> + + {count} + + ); +} + +export default App; +```
diff --git a/assets/img/react-http-fetch-logo.png b/assets/img/react-http-fetch-logo.png new file mode 100644 index 0000000..784d720 Binary files /dev/null and b/assets/img/react-http-fetch-logo.png differ diff --git a/src/events-manager/index.ts b/src/events-manager/index.ts index 3700a9b..5a153b0 100644 --- a/src/events-manager/index.ts +++ b/src/events-manager/index.ts @@ -1,5 +1,5 @@ export * from './event-bus'; export * from './event-bus-context'; export * from './types'; -export * from './use-bus-subscribe'; +export * from './use-http-event'; export * from './events'; diff --git a/src/events-manager/use-bus-subscribe.ts b/src/events-manager/use-http-event.ts similarity index 85% rename from src/events-manager/use-bus-subscribe.ts rename to src/events-manager/use-http-event.ts index f471d20..a777c8e 100644 --- a/src/events-manager/use-bus-subscribe.ts +++ b/src/events-manager/use-http-event.ts @@ -4,8 +4,8 @@ import { HttpEventClassType, HttpEventHandler } from './types'; import { useEventBus } from './event-bus-context'; import { useCompareLayoutEffect } from '../shared/use-compare-layout-effect'; -export const useBusSubscribe = ( - eventName: HttpEventClassType, +export const useHttpEvent = ( + eventType: HttpEventClassType, handler: HttpEventHandler ): void => { // The event bus. @@ -31,14 +31,14 @@ export const useBusSubscribe = ( useCompareLayoutEffect( () => { // Subscribe to the event and keep track of the subscription. - unsubscribeRef.current = eventBus.subscribe(eventName, handler); + unsubscribeRef.current = eventBus.subscribe(eventType, handler); // Clean up: unsubscribe the previous event handler. return () => { unsubscribe(); }; }, - [eventBus, eventName, handler, unsubscribe], + [eventBus, eventType, handler, unsubscribe], fastCompare ); };