WARNING: not maintained, feel free to fork and use in any way
npm i axios use-axios-react
- Hooks for ✅ data fetching ✅ CRUD ✅ Batch operations
- ✅ Request cancellation
- ✅ Retry/reload callbacks
- ✅ Zero-configuration, yet fully configurable when needed
- ✅ No app architecture commitments, drop in into your React and Axios project and start using hooks in your new components
- No extra-dependencies (React and Axios are peer dependencies), thus minimum overhead if your project already uses axios
- All axios features
npm i use-axios-react
Make sure axios itself is installed
npm i axios
And make sure you use React v16.8.0 or newer.
Basic data fetching (GET)
import React from "react"; import { useGetData } from "use-axios-react"; const KanyeQuote = () => { const [data, loading] = useGetData("https://api.kanye.rest/"); if (loading) return <div>Loading...</div>; return <blockquote>{data.quote}</blockquote>; };
Cancellable fetching (GET) with reload and retry
import React from "react"; import { useGetData } from "use-axios-react"; const KanyeQuote = () => { const [data, loading, { error, retry }] = useGetData("https://api.kanye.rest/", { cancelable: true }); if (loading) return <Spinner />; if (error) return <Button onClick={retry} label="RETRY" />; return ( <div> <Quote>{data.quote}</Quote> <Button onClick={retry} label="RELOAD" /> </Fragment> ); };
Basic POST example
import React from "react"; import { usePostCallback } from "use-axios-react"; function userToRequest({ name, job }) { return { url: "https://reqres.in/api/users", data: { name, job } }; } const CreateUser = () => { const [create, sending, { error, data }] = usePostCallback(userToRequest); const neo = { name: "Neo", job: "The One" }; const morpheus = { name: "Morpheus", job: "Leader" }; return ( <Layout> <Button onClick={() => create(neo)}>Neo</Button> <Button onClick={() => create(morpheus)}>Morpheus</Button> <StatusBar sending={sending} error={error} lastUser={data} /> </Layout> ); };
Pagination
import React, { useState } from "react"; import { useGetData } from "use-axios-react"; const PaginatedKanyeQuotes = () => { const [page, setPage] = useState(1); const [data, loading] = useGetData( { url: "https://api.kanye.rest/", params: { page } }, { cancelable: true } ); if (loading) return <Spinner />; const prev = () => setPage(page - 1); const next = () => setPage(page + 1); return ( <div> <Quote>{data.quote}</Quote> <div> <Button onClick={prev} disabled={page <= 1} label="← Prev" /> <span className="mx-5">Page {page}</span> <Button onClick={next} disabled={page >= 9} label="Next →" /> </div> </div> ); };
Basic TodoMVC CRUD
import React from "react"; import axios from "axios"; import { provideAxiosInstance, useGetData, usePostCallback, useDeleteCallback, usePatchCallback } from "use-axios-react"; provideAxiosInstance( axios.create({ baseURL: "https://todo-backend-golang-goa.herokuapp.com" }) ); /** * Map todos to axios request configs */ const todoObjectToAxiosRequest = ({ id, title, order, completed }) => ({ url: id ? `/todos/${id}` : "/todos", data: { title, order, completed } }); const TodoMvcApp = () => { // Reusing the same mapping function for all CRUD requests const [create, creating, { error: createError }] = usePostCallback(todoObjectToAxiosRequest); const [remove, removing, { error: removeError }] = useDeleteCallback(todoObjectToAxiosRequest); const [update, updating, { error: updateError }] = usePatchCallback(todoObjectToAxiosRequest); // Re-fetch after any of actions is completed const allRequestsDone = !creating && !removing && !updating; const [todos = [], fetching, { error: fetchError }] = useGetData("/todos", { // The hook will re-run every time `depends` changes depends: [creating, removing, updating], // Actual request will be performed only if this is true willRun: allRequestsDone }); if (createError || removeError || updateError || fetchError) { return <div>Error occurred, please reload</div>; } return ( <Layout> <Header loading={creating || removing || updating || fetching}> <NewTodo create={create} /> </Header> <TodoList todos={todos} remove={remove} update={update} loading={fetching} /> </Layout> ); };
Common state GET & POST
import React, { useEffect } from "react"; import { useGetData, usePostCallback } from "use-axios-react"; const CreateUser = () => { // Do an initial load const [users = [], loading, { error: loadError, setData: setUsers }] = useGetData("https://reqres.in/api/users"); // We're particularly interested in the create() callback and the response data (new user data) const [create, creating, { error: createError, data: newUser }] = usePostCallback("https://reqres.in/api/users"); // Update users state evey time the newUser changes useEffect( () => { newUser && setUsers([...users, newUser]); }, [newUser] ); return ( <Layout> <Button onClick={() => create({})}>Create dummy user</Button> <span>{(loading || creating) && "Loading..."}</span> <span>{(loadError || createError) && "Error occurred"}</span> <UserList users={users} /> </Layout> ); };
Using custom axios instance
import React from "react"; import ReactDOM from "react-dom"; import axios from "axios"; import { provideAxiosInstance, useGetData } from "use-axios-react"; const customAxiosInstance = axios.create({ baseURL: "https://reqres.in/api", transformResponse: axios.defaults.transformResponse.concat(data => { return data.data; }) }); provideAxiosInstance(customAxiosInstance); function App() { const [users, loading] = useGetData("/users"); if (loading) return "Loading..."; return ( <div> <h1>Users:</h1> <code>{JSON.stringify(users)}</code> </div> ); }
useGetData() | Use this one if you need to fetch data depending on some state (e.g. to fetch search results depending on search term) |
usePostCallback() usePutCallback() usePatchCallback() useDeleteCallback() useGetCallback() | Use this if you need to create callbacks to trigger a request programmatically |
useParallelPostCallback() useParallelPutCallback() useParallelPatchCallback() useParallelDeleteCallback() useParallelGetCallback() | Use this if you need to create callbacks to trigger batch requests |
provideAxiosInstance() | Provide a custom axios instance to use with the hooks |
url|axiosConfig
— Refer to axios request config documentation for detailsoptions
— Theuse{...}Data
hook options:
cancelable: bool | Whether the request should be canceled on component unmount |
depends: [] | Hook's effect will be re-run only if one of the passed array values changes. Refer to the React useEffect(effect, depends) second argument docs to learn how it works. |
willRun: bool | Request will be be executed only if this option is true. This is usually an expression such as willRun: !loading |
- result array structure is
[data, loading, { error, response, retry, retriesCount, setData }]
:
Where {Method} is one of the following: Post, Put, Patch, Delete, Get
url|axiosConfig|factory
— Request URL, axios config object or factory, producing an axios config object from callback args
- result array structure is
[exec, loading, { error, retry, response, data, execCount, input }]
:
Where {Method} is one of the following: Post, Put, Patch, Delete, Get
axiosConfigFactory
— A function producing an axios config object from callback args
- result array structure is
[exec, loading, { retry, errors, responses, data, succeed, failed, execCount, input }]