Redux Thunk Là Gì

     

Xin chào, lúc này mình xin ra mắt đến mọi fan cách xử lý những action bất đồng nhất trong Redux bằng việc thực hiện Redux thunk. Hình như cũng sẽ có tác dụng 1 ví dụ để các bạn có thể nắm rõ hơn về kiểu cách sử dụng redux-thunk

*
Bài viết gốc tại đây: https://www.juliandong.com/2020/03/xu-ly-asynchronous-redux-action-voi.html

1. Giới thiệu

Trong nội dung bài viết lần trước của bản thân mình tại đây và đây, bản thân đã ra mắt về Redux và những áp dụng nó vào trong một project React. Trong đó, mọi action trong redux đa số đồng bộ, có nghĩa là state sẽ tiến hành update ngay mau chóng khi action được dispatch.Vậy sẽ ra sao nếu kích hoạt của họ là sự không tương đồng bộ, tức là action phải gọi mang lại 1 API bên phía ngoài để lấy tài liệu hoặc tiến hành 1 side-effect khiến cho tác dụng không thể trả về ngay nhanh chóng được?

Rất may mắn Redux có cung cấp các middleware nhằm xử lý vụ việc với asynchronous kích hoạt và side effect. Danh tiếng nhất là redux-thunk với redux-saga. Trong phạm vi bài viết này bản thân sẽ reviews với các bạn về redux-thunk.

Bạn đang xem: Redux thunk là gì

2. Redux-thunk và asynchronous actions

Asynchronous actions

Khi ta call 1 API bất đồng bộ, gồm 2 thời điểm ta buộc phải quan tâm:

Thời điểm ban đầu gọiThời điểm cảm nhận kết quả

Tại mỗi thời khắc trên ta hồ hết cần biến hóa state của ứng dụng, và để triển khai điều đó, ta bắt buộc dispatch những kích hoạt mà sẽ tiến hành reducer xử lý một bí quyết đồng bộ. Thông thường với từng API call ta nên dispatch 3 một số loại action

Action thông tin cho reducer là ban đầu thực hiện tại API call: Reducer sẽ xử lý action này bằng việc đổi khác cờ loading hoặc isFetching trong state. Lúc đó UI sẽ hiển 1 spinner biểu hiện dữ liệu đang rất được xử lýAction thông tin cho reducer là vấn đề gọi API thành công: Reducer sẽ xử lý action này bằng việc cập nhật kết trái trả về trường đoản cú API và đồng thời tắt cờ loading. UI khi ấy sẽ ẩn spinner và hiển thị hiệu quả Action thông tin cho reducer là hotline thất bại : Reducer đang reset lại cờ loading , gìn giữ error vào state cùng hiển thị error message sinh sống UI

redux-thunk

thunk: là 1 trong những cách điện thoại tư vấn khác của function, cơ mà nó có 1 điểm nhất là nó là 1 trong những hàm được trả về từ 1 hàm khác.

Như bọn họ đã biết về action trong redux chỉ đối chọi thuần là phần nhiều plain object bao gồm chứa 1 field là type và bất cứ dữ liệu nào ta mong muốn thêm vào

"type": "ACTION_TYPE", "payload" :"Anything you want"Và action creator là 1 trong những hàm trả về về một action (plain object)

const actionCreator = (data) => ( type: "ACTION_TYPE", payload: data)Đối cùng với redux-thunk, nó là 1 trong những middleware cho phép action creator trả về một function (thunk) thay bởi vì trả về plain object. Function này đang nhận tham số là hàm dispatch của store, và nó đã dispatch những action một biện pháp đồng bộ bên phía trong thunk khi nhưng asynchronous gọi được gọi. Nói các khác, use-case thường thì nhất của redux-thunk là lúc lấy tài liệu từ external API, redux-thunk có thể chấp nhận được dispatch các action theo lifecycle của request mang đến API ngoài.

Xem thêm: Ăn Dừa Có Giảm Cân Không - Cơm Dừa Có Làm Bạn Tăng Cân Không

Ví dụ: ta nên fetch dữ liệu của 1 API, đầu tiên ta đang dispatch 1 kích hoạt để báo rằng dữ liệu đang rất được fetch, rồi tiếp đó nếu tác dụng trả về thành công, ta vẫn dispatch 1 kích hoạt để báo rằng câu hỏi fetch dữ liệu đã ngừng và cảm nhận kết quả. Nếu việc fetch thất bại, ta đang dispatch 1 action để báo rằng việc fetch dữ liệu xong xuôi và nhấn về lỗi.

Xem thêm: Nguyên Nhân Gây Buốt Nhức Chân Răng Phải Làm Sao Cho Hết, Đau Nhức Răng

Để nắm rõ hơn về redux-thunk được sử dụng ra làm sao trong thực tế, bọn họ sẽ đi qua 1 demo tại phần tiếp theo.

3. Demo

Trong lấy một ví dụ này, mình sẽ tạo nên ra 1 react ứng dụng có nhiệm vụ tìm kiếm user name từ bỏ github bằng việc sử dụng react, redux và redux-thunk

Khởi chế tạo project và cài đặt các package yêu cầu thiết

Mình sẽ cần sử dụng create react app để khởi tạo project

$ npm init react-app react-thunk # init project$ cd react-thunk $ npm i redux redux-thunk axios # install packagesSau lúc khởi chế tạo ra xong, chúng ta tiến hành kết cấu lại folder src như sau:

src/components: chứa những component cần sử dụng trong ứng dụngsrc/actions: chứa kích hoạt của reduxsrc/reducer: cất store và reducerssrc/service: các service để hotline APIsrc/style: đựng file css

Setup redux

Trong src/index.js

import React from "react";import ReactDOM from "react-dom";import "./index.css";import tiện ích from "./components/App";import Provider from "react-redux";import store from "./reducer/store";import * as serviceWorker from "./serviceWorker";ReactDOM.render( , document.getElementById("root"));serviceWorker.unregister();Thêm redux thunk vào src/reducer/store.js

import createStore, applyMiddleware from "redux";import thunk from "redux-thunk";import rootReducer from "./reducers";export const store = createStore(rootReducer, applyMiddleware(thunk));

Viết service hotline API

Trong src/services/index.js

import axios from "axios";const fetchUserService = username => return new Promise((resolve, reject) => axios.get(`https://api.github.com/users/$username`) .then(response => resolve(response.data)) .catch(error => reject(error)) )export mặc định fetchUserService;

Tạo action

Trong src/actions/fetchUser.js

import FETCH_USER, FETCH_USER_FAILED, FETCH_USER_SUCCESS from "./constants";import fetchUserSerivce from "../services";export default username => return dispatch => dispatch(fetchUser()); fetchUserSerivce(username) .then(user => dispatch(fetchUserSuccess(user))) .catch(error => dispatch(fetchUserFailed(error))) const fetchUser = () => ( type: FETCH_USER);const fetchUserSuccess = user => ( type: FETCH_USER_SUCCESS, payload: user ,)const fetchUserFailed = error => ( type: FETCH_USER_FAILED, payload: error )

Tạo reducer

Trong src/reducer/reducers.js

import FETCH_USER, FETCH_USER_SUCCESS, FETCH_USER_FAILED from "../actions/constants";const initialState = loading: false, error: null, user: nullexport const rootReducer = (state = initialState, action) => switch (action.type) case FETCH_USER: return loading: true, user: null, error: null, ; case FETCH_USER_SUCCESS: return loading: false, user: action.payload.user, error: null, ; case FETCH_USER_FAILED: return loading: false, user: null, error: action.payload.error default: return state; Như vậy chúng ta đã thiết lập redux xong, giờ đang hiện thực UI components

Search bar

Trong src/components/SearchBar.js

import React from "react";import fetchUser from "../actions/fetchUser";import connect from "react-redux";import "../style/SearchBar.css"class SearchBar extends React.Component { constructor(props) super(props); this.state = username: "" this._onChange = this._onChange.bind(this); this._onSubmit = this._onSubmit.bind(this); _onChange(event) const value = event.target.value; this.setState( username: value ) _onSubmit(event) event.preventDefault(); this.props.fetchUser(this.state.username) render() { return (