Axios или fetch
Содержание:
- Interceptors
- Composing with Components
- Using application/x-www-form-urlencoded format
- Организация кода
- axios API
- Cancellation
- Request Config
- Using application/x-www-form-urlencoded format
- Request Config
- Interceptors
- axios API
- axios-observable API
- Шаблон компонента
- Но почему?
- Declarative Rendering
- Config Defaults
- axios API
- axios API
- Request Config
- Interceptors
- Example
- Загрузка нескольких файлов
- Request Options
- API
- Config Defaults
- Server Side Rendering
Interceptors
You can intercept requests or responses before they are handled by or .
axios.interceptors.request.use(function(config){return config;},function(error){returnPromise.reject(error);});axios.interceptors.response.use(function(response){return response;},function(error){returnPromise.reject(error);});
If you may need to remove an interceptor later you can.
var myInterceptor =axios.interceptors.request.use(function(){});axios.interceptors.request.eject(myInterceptor);
You can add interceptors to a custom instance of axios.
var instance =axios.create();instance.interceptors.request.use(function(){});
Composing with Components
The component system is another important concept in Vue, because it’s an abstraction that allows us to build large-scale applications composed of small, self-contained, and often reusable components. If we think about it, almost any type of application interface can be abstracted into a tree of components:
In Vue, a component is essentially a Vue instance with pre-defined options. Registering a component in Vue is straightforward:
Now you can compose it in another component’s template:
But this would render the same text for every todo, which is not super interesting. We should be able to pass data from the parent scope into child components. Let’s modify the component definition to make it accept a :
Now we can pass the todo into each repeated component using :
This is a contrived example, but we have managed to separate our app into two smaller units, and the child is reasonably well-decoupled from the parent via the props interface. We can now further improve our component with more complex template and logic without affecting the parent app.
In a large application, it is necessary to divide the whole app into components to make development manageable. We will talk a lot more about components later in the guide, but here’s an (imaginary) example of what an app’s template might look like with components:
Relation to Custom Elements
You may have noticed that Vue components are very similar to Custom Elements, which are part of the Web Components Spec. That’s because Vue’s component syntax is loosely modeled after the spec. For example, Vue components implement the Slot API and the special attribute. However, there are a few key differences:
-
The Web Components Spec has been finalized, but is not natively implemented in every browser. Safari 10.1+, Chrome 54+ and Firefox 63+ natively support web components. In comparison, Vue components don’t require any polyfills and work consistently in all supported browsers (IE9 and above). When needed, Vue components can also be wrapped inside a native custom element.
-
Vue components provide important features that are not available in plain custom elements, most notably cross-component data flow, custom event communication and build tool integrations.
Although Vue doesn’t use custom elements internally, it has when it comes to consuming or distributing as custom elements. Vue CLI also supports building Vue components that register themselves as native custom elements.
Using application/x-www-form-urlencoded format
By default, axios serializes JavaScript objects to . To send data in the format instead, you can use one of the following options.
constparams=newURLSearchParams();params.append('param1','value1');params.append('param2','value2');axios.post('/foo', params);
constqs=require('qs');axios.post('/foo',qs.stringify({'bar'123}));
Or in another way (ES6),
importqsfrom'qs';constdata={'bar'123};constoptions={ method'POST', headers{'content-type''application/x-www-form-urlencoded'}, dataqs.stringify(data), url,};axios(options);
constquerystring=require('querystring');axios.post('http://something.com/',querystring.stringify({ foo'bar'}));
Организация кода
Сохранение всех переменных состояния, геттеров, действий и мутаций в одном файле быстро сделает его громоздким, как только вы начнете работать с большими приложениями. Давайте посмотрим, как можно организовать хранилище в нескольких файлах в виде модулей.
Создайте новую директорию внутри вашего хранилища и назовите ее modules. Добавьте в созданную директорию файл todos.js, содержащий следующий код:
Теперь мы можем переместить переменные состояния, геттеры, мутации и действия из файла index.js в файл todos.js. Не забудьте импортировать Axios. Все, что нам нужно сделать, это дать знать Vuex о том, что мы создали модуль хранилища и где его можно найти. Обновленный файл index.js должен выглядеть примерно так:
Файл todos.js будет выглядеть так:
axios API
Requests can be made by passing the relevant config to .
axios({ method'post', url'/user/12345', data{ firstName'Fred', lastName'Flintstone'}});
axios('/user/12345');
For convenience aliases have been provided for all supported request methods.
When using the alias methods , , and properties don’t need to be specified in config.
Helper functions for dealing with concurrent requests.
You can create a new instance of axios with a custom config.
var instance =axios.create({ baseURL'https://some-domain.com/api/', timeout1000, headers{'X-Custom-Header''foobar'}});
The available instance methods are listed below. The specified config will be merged with the instance config.
Cancellation
You can cancel a request using a cancel token.
You can create a cancel token using the factory as shown below:
constCancelToken=axios.CancelToken;constsource=CancelToken.source();axios.get('/user/12345',{ cancelTokensource.token}).catch(function(thrown){if(axios.isCancel(thrown)){console.log('Request canceled',thrown.message);}else{}});axios.post('/user/12345',{ name'new name'},{ cancelTokensource.token})source.cancel('Operation canceled by the user.');
You can also create a cancel token by passing an executor function to the constructor:
constCancelToken=axios.CancelToken;let cancel;axios.get('/user/12345',{ cancelTokennewCancelToken(functionexecutor(c){ cancel = c;})});cancel();
Request Config
These are the available config options for making requests. Only the is required. Requests will default to if is not specified.
{ url'/user', method'get', baseURL'https://some-domain.com/api/', transformRequestfunction(data,headers){return data;}, transformResponsefunction(data){return data;}, headers{'X-Requested-With''XMLHttpRequest'}, params{ID12345},paramsSerializerfunction(params){returnQs.stringify(params,{arrayFormat'brackets'})}, data{ firstName'Fred'}, data'Country=Brasil&City=Belo Horizonte', timeout1000, withCredentialsfalse,adapterfunction(config){}, auth{ username'janedoe', password's00pers3cret'}, responseType'json', responseEncoding'utf8', xsrfCookieName'XSRF-TOKEN', xsrfHeaderName'X-XSRF-TOKEN',onUploadProgressfunction(progressEvent){},onDownloadProgressfunction(progressEvent){}, maxContentLength2000, maxBodyLength2000,validateStatusfunction(status){return status >=200&& status <300;}, maxRedirects5, socketPathnull, httpAgentnewhttp.Agent({ keepAlivetrue}), httpsAgentnewhttps.Agent({ keepAlivetrue}), proxy{ host'127.0.0.1', port9000, auth{ username'mikeymike', password'rapunz3l'}}, cancelTokennewCancelToken(function(cancel){}), decompresstrue}
Using application/x-www-form-urlencoded format
By default, axios serializes JavaScript objects to . To send data in the format instead, you can use one of the following options.
Browser
const params = new URLSearchParams(); params.append('param1', 'value1'); params.append('param2', 'value2'); Axios.post('/foo', params);
Alternatively, you can encode data using the library:
const qs = require('qs'); Axios.post('/foo', qs.stringify({ 'bar': 123 }));
Or in another way (ES6),
import qs from 'qs'; const data = { 'bar': 123 }; const options = { method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, data: qs.stringify(data), url, }; Axios.request(options);
Node.js
const querystring = require('querystring'); Axios.post('http://something.com/', querystring.stringify({ foo: 'bar' }));
You can also use the library.
Request Config
These are the available config options for making requests. Only the is required. Requests will default to if is not specified.
{ url'/user', method'get', baseURL'https://some-domain.com/api/', transformRequestfunction(data){return data;}, transformResponsefunction(data){return data;}, headers{'X-Requested-With''XMLHttpRequest'}, params{ID12345},paramsSerializerfunction(params){returnQs.stringify(params,{arrayFormat'brackets'})}, data{ firstName'Fred'}, timeout1000, withCredentialsfalse,adapterfunction(config){}, auth{ username'janedoe', password's00pers3cret'}, responseType'json', xsrfCookieName'XSRF-TOKEN', xsrfHeaderName'X-XSRF-TOKEN',onUploadProgressfunction(progressEvent){},onDownloadProgressfunction(progressEvent){}, maxContentLength2000,validateStatusfunction(status){return status >=200&& status <300;}, maxRedirects5, httpAgentnewhttp.Agent({ keepAlivetrue}), httpsAgentnewhttps.Agent({ keepAlivetrue}), proxy{ host'127.0.0.1', port9000, auth{ username'mikeymike', password'rapunz3l'}}, cancelTokennewCancelToken(function(cancel){})}
Interceptors
You can intercept requests or responses before they are handled by or .
axios.interceptors.request.use(function(config){return config;},function(error){returnPromise.reject(error);});axios.interceptors.response.use(function(response){return response;},function(error){returnPromise.reject(error);});
If you may need to remove an interceptor later you can.
constmyInterceptor=axios.interceptors.request.use(function(){});axios.interceptors.request.eject(myInterceptor);
You can add interceptors to a custom instance of axios.
constinstance=axios.create();instance.interceptors.request.use(function(){});
axios API
Requests can be made by passing the relevant config to .
axios({ method'post', url'/user/12345', data{ firstName'Fred', lastName'Flintstone'}});
axios({ method'get', url'http://bit.ly/2mTM3nY', responseType'stream'}).then(function(response){response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))});
axios('/user/12345');
For convenience aliases have been provided for all supported request methods.
When using the alias methods , , and properties don’t need to be specified in config.
Please use to replace the below functions.
Helper functions for dealing with concurrent requests.
axios.all(iterable)
axios.spread(callback)
You can create a new instance of axios with a custom config.
constinstance=axios.create({ baseURL'https://some-domain.com/api/', timeout1000, headers{'X-Custom-Header''foobar'}});
The available instance methods are listed below. The specified config will be merged with the instance config.
axios-observable API
Yeah! We use the exact same config object as axios.
The example below is wrong!
// Send a POST request Axios({ method: 'post', url: '/user/12345', data: { firstName: 'Fred', lastName: 'Flintstone' } });
use Axios.request(config) instead
// Send a POST request Axios.request({ method: 'post', url: '/user/12345', data: { firstName: 'Fred', lastName: 'Flintstone' } });
// GET request for remote image Axios.request({ method:'get', url:'http://bit.ly/2mTM3nY', responseType:'stream' }) .subscribe(response => { response.data.pipe(fs.createWriteStream('ada_lovelace.jpg')) });
Request method aliases
For convenience aliases have been provided for all supported request methods.
Axios.patch(url])
NOTE
When using the alias methods , , and properties don’t need to be specified in config.
Creating an instance
You can create a new instance of Axios with a custom config.
Axios.create()
const instance = Axios.create({ baseURL: 'https://some-domain.com/api/', timeout: 1000, headers: {'X-Custom-Header': 'foobar'} });
Instance methods
The available instance methods are listed below. The specified config will be merged with the instance config.
Шаблон компонента
Теперь нам нужно добавить наш шаблон, поэтому добавим следующее в тег template:
<template> <div class="container"> <div class="large-12 medium-12 small-12 cell"> <label>File <input type="file" id="file" ref="file" v-on:change="handleFileUpload()"/> </label> <br> <progress max="100" :value.prop="uploadPercentage"></progress> <br> <button v-on:click="submitFile()">Submit</button> </div> </div> </template>
Есть пара вещей, на которые стоит обратить внимание. Наш input имеет атрибут ref=»file»
Это позволяет сделать input доступным через локальную переменную $refs в нашем компоненте. Далее мы ожидаем, когда пользователь начнет загружать файл. В этот момент, мы копируем выбранный файл в локальную переменную file (которую мы добавим на следующем шаге), чтобы мы могли отправить его на сервер.
Самым важным элементом шаблона является элемент <progress>. Через него мы семантически отобразим ход загрузки файлов. Есть пара атрибутов, которые указывают на элемент. Первым является атрибут max. Мы установили его на 100, так как мы будем вычислять процент на основе 100.
Следующий атрибут в элементе <progress> — это атрибут :value.prop=»uploadPercentage». Поскольку элемент <progress> не является input, его значение является атрибутом, а не фактическим значением, которое имеет элемент input. Мы привязываем значение value в виде prop (с :value.prop) к вычисленному uploadPercentage. На следующем шаге мы добавим данные для uploadPercentage.
Последнее замечание о шаблоне — кнопка «Submit», при нажатии на которую запускается метод submitFile(). Это метод просто отправляет файл на сервер.
Но почему?
Возможно, вам интересно, почему требуется объявление действия, если мы можем просто инициировать мутации с новым значением непосредственно из наших компонентов. Как упоминалось выше, мутации являются синхронными, а действий — нет.
В приведенном выше примере рассмотрен случай, когда вам нужно обновить значение имени, но не только в своем состоянии, а еще и в базе данных, запущенной на удаленном сервере. Я уверен, что именно так вы собираетесь использовать Vuex в реальном проекте в 99% случаев. Взгляните на следующий фрагмент кода:
Сам код не требует пояснений. Мы используем Axios для отправки имени на эндпоинт. Если POST-запрос выполнен успешно, и значение имени поля было успешно изменено на сервере, мы инициируем мутацию SET_ NAME для обновления значения имени внутри нашего состояния.
ВОЗЬМИТЕ ЗА ПРАКТИКУ НИКОГДА НЕ ИНИЦИИРОВАТЬ МУТАЦИИ НАПРЯМУЮ. ДЛЯ ЭТОГО ВСЕГДА ИСПОЛЬЗУЙТЕ ДЕЙСТВИЯ.
Declarative Rendering
At the core of Vue.js is a system that enables us to declaratively render data to the DOM using straightforward template syntax:
{{ message }}
We have already created our very first Vue app! This looks pretty similar to rendering a string template, but Vue has done a lot of work under the hood. The data and the DOM are now linked, and everything is now reactive. How do we know? Open your browser’s JavaScript console (right now, on this page) and set to a different value. You should see the rendered example above update accordingly.
Note that we no longer have to interact with the HTML directly. A Vue app attaches itself to a single DOM element ( in our case) then fully controls it. The HTML is our entry point, but everything else happens within the newly created Vue instance.
In addition to text interpolation, we can also bind element attributes like this:
Hover your mouse over me for a few seconds to see my dynamically bound title!
Here we are encountering something new. The attribute you are seeing is called a directive. Directives are prefixed with to indicate that they are special attributes provided by Vue, and as you may have guessed, they apply special reactive behavior to the rendered DOM. Here, it is basically saying “keep this element’s attribute up-to-date with the property on the Vue instance.”
If you open up your JavaScript console again and enter , you’ll once again see that the bound HTML — in this case the attribute — has been updated.
Config Defaults
You can specify config defaults that will be applied to every request.
axios.defaults.baseURL='https://api.example.com';axios.defaults.headers.common'Authorization'=AUTH_TOKEN;axios.defaults.headers.post'Content-Type'='application/x-www-form-urlencoded';
var instance =axios.create({ baseURL'https://api.example.com'});instance.defaults.headers.common'Authorization'=AUTH_TOKEN;
Config will be merged with an order of precedence. The order is library defaults found in , then property of the instance, and finally argument for the request. The latter will take precedence over the former. Here’s an example.
var instance =axios.create();instance.defaults.timeout=2500;instance.get('/longRequest',{ timeout5000});
axios API
Requests can be made by passing the relevant config to .
axios({ method'post', url'/user/12345', data{ firstName'Fred', lastName'Flintstone'}});
axios({ method'get', url'http://bit.ly/2mTM3nY', responseType'stream'}).then(function(response){response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))});
axios('/user/12345');
For convenience aliases have been provided for all supported request methods.
When using the alias methods , , and properties don’t need to be specified in config.
Helper functions for dealing with concurrent requests.
You can create a new instance of axios with a custom config.
constinstance=axios.create({ baseURL'https://some-domain.com/api/', timeout1000, headers{'X-Custom-Header''foobar'}});
The available instance methods are listed below. The specified config will be merged with the instance config.
axios API
Requests can be made by passing the relevant config to .
axios({ method'post', url'/user/12345', data{ firstName'Fred', lastName'Flintstone'}});
axios('/user/12345');
For convenience aliases have been provided for all supported request methods.
When using the alias methods , , and properties don’t need to be specified in config.
Helper functions for dealing with concurrent requests.
You can create a new instance of axios with a custom config.
var instance =axios.create({ baseURL'https://some-domain.com/api/', timeout1000, headers{'X-Custom-Header''foobar'}});
The available instance methods are listed below. The specified config will be merged with the instance config.
Request Config
These are the available config options for making requests. Only the is required. Requests will default to if is not specified.
{ url'/user', method'get', baseURL'https://some-domain.com/api/', transformRequestfunction(data,headers){return data;}, transformResponsefunction(data){return data;}, headers{'X-Requested-With''XMLHttpRequest'}, params{ID12345},paramsSerializerfunction(params){returnQs.stringify(params,{arrayFormat'brackets'})}, data{ firstName'Fred'}, timeout1000, withCredentialsfalse,adapterfunction(config){}, auth{ username'janedoe', password's00pers3cret'}, responseType'json', xsrfCookieName'XSRF-TOKEN', xsrfHeaderName'X-XSRF-TOKEN',onUploadProgressfunction(progressEvent){},onDownloadProgressfunction(progressEvent){}, maxContentLength2000,validateStatusfunction(status){return status >=200&& status <300;}, maxRedirects5, httpAgentnewhttp.Agent({ keepAlivetrue}), httpsAgentnewhttps.Agent({ keepAlivetrue}), proxy{ host'127.0.0.1', port9000, auth{ username'mikeymike', password'rapunz3l'}}, cancelTokennewCancelToken(function(cancel){})}
Interceptors
You can intercept requests or responses before they are handled by or .
axios.interceptors.request.use(function(config){return config;},function(error){returnPromise.reject(error);});axios.interceptors.response.use(function(response){return response;},function(error){returnPromise.reject(error);});
If you need to remove an interceptor later you can.
constmyInterceptor=axios.interceptors.request.use(function(){});axios.interceptors.request.eject(myInterceptor);
You can add interceptors to a custom instance of axios.
constinstance=axios.create();instance.interceptors.request.use(function(){});
Example
Performing a request
import Axios from 'axios-observable'; // or const Axios = require('axios-observable').Axios; // Make a request for a user with a given ID Axios.get('/user?ID=12345') .subscribe( response => console.log(response), error => console.log(error) ); // Optionally the request above could also be done as Axios.get('/user?ID=12345'), { params: { ID: 12345 } }) .subscribe( response => console.log(response), error => console.log(error) );
Performing a request
Axios.post('/user', { firstName: 'Fred', lastName: 'Flintstone' }) .subscribe( response => console.log(response), error => console.log(error) );
Загрузка нескольких файлов
Обработка нескольких файлов очень похожа на загрузку одиного файла. Мы начнем с шаблона, который будет выглядеть следующим образом в нашем компоненте Vue:
<template> <div class="container"> <div class="large-12 medium-12 small-12 cell"> <label>Files <input type="file" id="files" ref="files" multiple v-on:change="handleFileUploads()"/> </label> <button v-on:click="submitFiles()">Submit</button> </div> </div> </template>
Помимо изменения имени атрибута ref и изменения идентификатора на files, наиболее важным атрибутом является то, что мы добавили multiple к нашему input. Это позволит пользователю использовать cmd (ctrl) + клик, чтобы выбрать несколько файлов одновременно. В следующем разделе мы позволим пользователю удалять файлы и выбирать больше файлов, если они допустили ошибку .
Метод загрузки нескольких файлов handleFileUploads()
Он очень похож на загрузку одного файла, за исключением того, что мы добавим все файлы в наш массив, если пользователь выберет более одного. Во-первых, давайте добавим новое хранилище данных в компонент Vue и присвоим этой переменной имя files:
data(){ return { files: '' } },
Теперь у нас есть локальная переменная для хранения наших файлов. Теперь мы можем сделать наш метод handleFileUploads():
handleFilesUpload(){ this.files = this.$refs.files.files; }
Он позволяет получить все файлы из FilesList из нашей загрузки файлов и сохранить их локально.
Реализация метода submitFiles()
Теперь у нас все готово чтобы отправить все наши файлы на сервер! Во-первых, давайте добавим наш метод submitFiles() в массив методов:
submitFiles(){ },
Как и в последнем методе, сначала инициализируем объект FormData():
let formData = new FormData();
Теперь, переберем все выбранные файлы и добавить их в массив files, который мы собираемся отправить на сервер. Массив files будет ключом в объекте formData(), который мы будем отправлять на сервер:
for( var i = 0; i < this.files.length; i++ ){ let file = this.files; formData.append('files', file); }
Теперь мы готовы отправить наши файлы на сервер через Axios:
axios.post( '/multiple-files', formData, { headers: { 'Content-Type': 'multipart/form-data' } } ).then(function(){ console.log('SUCCESS!!'); }) .catch(function(){ console.log('FAILURE!!'); });
На стороне сервера вы можете получить доступ к файлам через ключ files, который является первым параметром formData.append(‘files’, file);.
В PHP это может быть: $_FILES, а в Laravel вы можете обращаться к нему через Request::file(‘files’) и выполнять любую обработку на стороне сервера, которая вам нужна. Теперь вы можете просмотреть все файлы, чтобы можно было загружать их несколько раз.
Наш компонент MultipleFiles.vue должен выглядеть следующим образом:
<template> <div class="container"> <div class="large-12 medium-12 small-12 cell"> <label>Files <input type="file" id="files" ref="files" multiple v-on:change="handleFilesUpload()"/> </label> <button v-on:click="submitFiles()">Submit</button> </div> </div> </template> <script> export default { /* Defines the data used by the component */ data(){ return { files: '' } }, methods: { submitFiles(){ let formData = new FormData(); for( var i = 0; i < this.files.length; i++ ){ let file = this.files; formData.append('files', file); } axios.post( '/multiple-files', formData, { headers: { 'Content-Type': 'multipart/form-data' } } ).then(function(){ console.log('SUCCESS!!'); }) .catch(function(){ console.log('FAILURE!!'); }); }, handleFilesUpload(){ this.files = this.$refs.files.files; } } } </script>
Следующим шагом мы позволим пользователям редактировать файлы, которые они выбрали, чтобы они случайно не загрузили файл, который им не нужен.
Request Options
{ // The url to which the request should be sent. Required. url: string, // The HTTP method to use for the request. Defaults to `GET`. method: 'GET', // The base Url to use for the request. Prepended to the `url` property above. baseURL: 'https://example.com'; // The HTTP methods to be sent with the request. headers: { 'some': 'header' }, // The data to send in the body of the request. Data objects will be serialized as JSON. data: { some: 'data' }, // The max size of the http response content in bytes allowed. // Defaults to `0`, which is the same as unset. maxContentLength: 2000, // The max number of HTTP redirects to follow. // Defaults to 100. maxRedirects: 100, // The querystring parameters that will be encoded using `qs` and // appended to the url params: { querystring: 'parameters' }, // By default, we use the `querystring` package in node core to serialize // querystring parameters. You can override that and provide your // own implementation. paramsSerializer: (params) => { return qs.stringify(params); }, // The timeout for the HTTP request. Defaults to 0. timeout: 1000, // Optional method to override making the actual HTTP request. Useful // for writing tests and instrumentation adapter?: async (options, defaultAdapter) => { const res = await defaultAdapter(options); res.data = { ...res.data, extraProperty: 'your extra property', }; return res; }; // The expected return type of the request. Options are: // json | stream | blob | arraybuffer | text // Defaults to `json`. responseType: 'json', // The node.js http agent to use for the request. agent: someHttpsAgent, // Custom function to determine if the response is valid based on the // status code. Defaults to (>= 200 && < 300) validateStatus: (status: number) => true, // Configuration for retrying of requests. retryConfig: { // The number of times to retry the request. Defaults to 3. retry?: number; // The number of retries already attempted. currentRetryAttempt?: number; // The HTTP Methods that will be automatically retried. // Defaults to httpMethodsToRetry?: string; // The HTTP response status codes that will automatically be retried. // Defaults to: , , ] statusCodesToRetry?: number; // Function to invoke when a retry attempt is made. onRetryAttempt?: (err: GaxiosError) => Promise<void> | void; // Function to invoke which determines if you should retry shouldRetry?: (err: GaxiosError) => Promise<boolean> | boolean; // When there is no response, the number of retries to attempt. Defaults to 2. noResponseRetries?: number; }, // Enables default configuration for retries. retry: boolean, // Cancelling a request requires the `abort-controller` library. // See https://github.com/bitinn/node-fetch#request-cancellation-with-abortsignal signal?: AbortSignal }
API
The package exports one default export and named exports:
The main React hook to execute HTTP requests.
-
— An options object.
- ( ) — If true, the request is not executed immediately. Useful for non-GET requests that should not be executed when the component renders. Use the function returned when invoking the hook to execute the request manually.
- ( ) — Allows caching to be enabled/disabled for the hook. It doesn’t affect the function returned by the hook.
Returns
-
— True if the request is in progress, otherwise False.
-
— A function to execute the request manually, bypassing the cache by default.
- — Same object as , which is shallow-merged with the config object provided when invoking the hook. Useful to provide arguments to non-GET requests.
- — An options object.
Returns
A promise containing the response. If the request is unsuccessful, an exception is thrown and must be handled manually.
Allows to provide custom instances of cache and axios.
Dumps the request-response cache, to use in server side rendering scenarios.
Returns
A serializable representation of the request-response cache ready to be used by
Populates the cache with serialized data generated by .
cache The serializable representation of the request-response cache generated by serializeCache
Creates an instance of the hook configured with the supplied cache and axios instance.
Returns
An instance of React Hook which will always use the provided cache and axios instance.
The returned value, besides being a function that can be used as a React Hook, also contains the properties:
which are the same as the package’s named exports but limited to the instance returned by .
Config Defaults
You can specify config defaults that will be applied to every request.
Global axios defaults
Axios.defaults.baseURL = 'https://api.example.com'; Axios.defaults.headers.common'Authorization' = AUTH_TOKEN; Axios.defaults.headers.post'Content-Type' = 'application/x-www-form-urlencoded';
Custom instance defaults
// Set config defaults when creating the instance const instance = Axios.create({ baseURL: 'https://api.example.com' }); // Alter defaults after instance has been created instance.defaults.headers.common'Authorization' = AUTH_TOKEN;
Config order of precedence
Config will be merged with an order of precedence. The order is library defaults found in , then property of the instance, and finally argument for the request. The latter will take precedence over the former. Here’s an example.
// Create an instance using the config defaults provided by the library // At this point the timeout config value is `0` as is the default for the library const instance = Axios.create(); // Override timeout default for the library // Now all requests using this instance will wait 2.5 seconds before timing out instance.defaults.timeout = 2500; // Override timeout for this request as it's known to take a long time instance.get('/longRequest', { timeout: 5000 });
Server Side Rendering
seamlessly supports server side rendering scenarios, by preloading data on the server and providing the data to the client, so that the client doesn’t need to reload it.
- the React component tree is rendered on the server
- HTTP requests are executed on the server
- the server code awaits in order to obtain a serializable representation of the request-response cache
- the server injects a JSON-serialized version of the cache in a global variable
- the client hydrates the cache from the global variable before rendering the application using
<script>window.__AXIOS_HOOKS_CACHE__={{{cache}}}</script>
import{serializeCache}from'axios-hooks'router.use(async(req,res)=>{constindex=fs.readFileSync(`${publicFolder}/index.html`,'utf8')consthtml=ReactDOM.renderToString(<App >)constcache=awaitserializeCache()res.send( index.replace('{{{html}}}', html).replace('{{{cache}}}',JSON.stringify(cache).replace(<g,'\\u003c')))})
import{loadCache}from'axios-hooks'loadCache(window.__AXIOS_HOOKS_CACHE__)deletewindow.__AXIOS_HOOKS_CACHE__ReactDOM.hydrate(<App >,document.getElementById('root'))