Next. Js Scaffolding advanced series

  • Perfect for Ant-Design
  • Package fetch && add middleware
  • The deployment of online

To encapsulate the fetch

First, let’s talk about why FETCH is used instead of Axios. There are two main points:

  • First, I used Axios in another express-react-scaffold with the idea of learning something new and wrapping fetch myself.
  • Secondly, I think fetch has more powerful functions, because FETCH is an API that is supported by native language and is more low-level, so it has better scalability. After encapsulation and expansion, FETCH should be very powerful. Since I have seen many mature scaffolds using FETCH, I think this view is acceptable. (P.S. Personal opinion, don’t spray if you don’t like it)

The response of the fetch

I think this is both the disadvantage of FETCH and the advantage of FETCH. Let’s first compare the difference between a normal fetch request and Axios

// fetch fetch(url).then(res => {// first layer res res.json() // then(r => {// second layer res console.log(r) // Get the last data})}); // axios(url). Then (res=>{// first layer res console.log(res); });Copy the code

As shown above, we need to perform res.json() on the fetch’s res before we get the JSON data we want, and Axios does this for us, making it much easier to use

This is a disadvantage ~ but!! We can completely solve this problem through encapsulation, and the next is why this is also the advantage of FETCH. First of all, let’s talk about why fetch requires two layers. The first layer is res.json(), because the response of fetch is an object integrating various methods, not the requested data. If we need a JSON object, res.json(). If we need a text string, res.text(). It can also fetch the blob content directly, res.blob(). In summary, FETCH is really, really powerful, depending on how good you are at encapsulating it.

In advance, I blew so long, in fact, I personally think I am not too good at using ha, the following package is a simple package, you see the officers according to the need to use, you can on my basis for their own projects for better packaging, or directly their own packaging can be.

The disadvantage of the fetch

  • The way you get the data is two-tier
  • Fetch only reports an error for network requests and considers 400,500 successful requests
  • Fetch does not carry cookies and needs to be configured
  • Fetch does not support timeout

.

Several disadvantages of FETCH have been mentioned above. In fact, these disadvantages can be remedied through encapsulation and plug-ins.

Encapsulate the fetch process and purpose

  • Humanized use, get, POST, PUT, delete, patch and other methods call
  • The method of retrieving data for most scenarios is direct res.json()
  • Support the timeout
  • Error handling
  • Working with log Components

Encapsulates the code

import fetch from 'isomorphic-unfetch'; import qs from 'query-string'; import { filterObject } from './util'; // initial fetch const nextFetch = Object.create(null); // browser support methods // ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PATCH', 'PUT'] const HTTP_METHOD = ['get', 'post', 'put', 'patch', 'delete']; // can send data method const CAN_SEND_METHOD = ['post', 'put', 'delete', 'patch']; HTTP_METHOD.forEach(method => { // is can send data in opt.body const canSend = CAN_SEND_METHOD.includes(method); nextFetch[method] = (path, { data, query, timeout = 5000 } = {}) => { let url = path; const opts = { method, headers: { 'Content-Type': 'application/x-www-form-urlencoded', Accept: 'application/json' }, credentials: 'include', timeout, mode: 'same-origin', cache: 'no-cache' }; if (query) { url += `${url.includes('? ')? '&' : '? '}${qs.stringify( filterObject(query, Boolean), )}`; } if (canSend && data) { opts.body = qs.stringify(filterObject(data, Boolean)); } console.info('Request Url:', url); return fetch(url, opts) .then(res => res.json()) .then(({ errcode = 0, errmsg, data }) => { if (errcode ! == 0) { const err = new Error(errmsg); err.message = errmsg; err.code = errcode; err.data = data; throw err; } return data; }); }; }); export default nextFetch;Copy the code

Use after encapsulation:

// /redux/sagas/user/userList.js ... import nextFetch from '.. /.. /.. /core/nextFetch'; export function* userList() { while (true) { yield take(FETCH_USER_LIST); Const data = yield nextFetch. Get (api.getUserList); // const res = yield fetch(api.getUserList); // const { data } = yield res.json(); yield put(fetchUserListDataSuccess(data)); } catch (error) { console.log(error.code, error.message, error.data); yield put(fetchUserListDataFali(error)); }}}Copy the code

The reason why isomorphic-unfetch is used is that Next. Js is server side rendering, which purports to be common to both front and back ends. The server side rendering framework I used before is separated, and the front and back ends use different FETCH (front-end is WHATWG-FETCH, The backend is Node-fetch).

Here is my own wrapper, I default back end to return a JSON format of data, and then the three fields {data, errcode, errmsg}, and the successful response code = 0. Friends make changes according to their own project structure.

Adding middleware

Redux middleware system, why add middleware, because above we added fetch error processing, so we can fail the request in advance processing in the middleware place ~

// /redux/store.js import userMiddleware from '.. /middlewares/client/user'; . Const bindMiddleware = (middleware) => {// add route middleware. Push (userMiddleware); . return applyMiddleware(... middleware); }; // /middles/client/user.js import { message } from 'antd'; import { FETCH_USER_LIST_FAIL } from '.. /.. /constants/ActionTypes'; Export default ({getState}) => next => Action => {// Redux middleware const ret = next(action); Switch (action.type) {case FETCH_USER_LIST_FAIL: {message.error(' Failed to get user list, please try again later '); break; } default: } return ret; };Copy the code

The effect is as follows:

conclusion

Today this is very simple, is not what advanced things, are readily used, but encapsulated to facilitate the use of some, feel the scaffolding to this really can directly carry out the development of the project, may also be a front-end log function, there is time to write front-end log ~

The code address