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 }]