Tuesday, March 9, 2021
Lưu Xuân Trường's Blog
  • Trang chủ
  • Backend
    • Laravel
    • Golang
    • NodeJS
    • MongoDB
    • Redis
    • WordPress
      • Kinh nghiệm
      • Plugins
  • Frontend
    • CSS
    • Javascript
      • ReactJS
      • UmiJS
      • VueJS
      • NuxtJS
      • Angular
      • RxJS
    • Game HTML5
  • Mobile
    • React Native
    • IOS
    • Android
    • Flutter
  • Tutorials
    • Redux-Saga
  • How to
  • Góc Ngoài Lề
    • Sống Chậm Nghĩ Sâu
    • Câu Hỏi Phỏng Vấn
    • IQ Test
  • Liên Hệ
No Result
View All Result
  • Trang chủ
  • Backend
    • Laravel
    • Golang
    • NodeJS
    • MongoDB
    • Redis
    • WordPress
      • Kinh nghiệm
      • Plugins
  • Frontend
    • CSS
    • Javascript
      • ReactJS
      • UmiJS
      • VueJS
      • NuxtJS
      • Angular
      • RxJS
    • Game HTML5
  • Mobile
    • React Native
    • IOS
    • Android
    • Flutter
  • Tutorials
    • Redux-Saga
  • How to
  • Góc Ngoài Lề
    • Sống Chậm Nghĩ Sâu
    • Câu Hỏi Phỏng Vấn
    • IQ Test
  • Liên Hệ
No Result
View All Result
Lưu Xuân Trường's Blog
No Result
View All Result

Watcher effect trong dvaJS

truongluu by truongluu
15/10/2020
in Javascript, ReactJS
Reading Time: 4min read
0 0
2
Watcher effect trong dvaJS
0
SHARES
118
VIEWS
Share on FacebookShare on Twitter

Trong DvaJS có 1 tính năng khá hay mà chắc ai cũng dùng tới hoặc sẽ có lúc cần sử dụng đó là theo dõi, được chia làm 2 loại.

  1. Theo dõi thay đổi từ đường dẫn của ứng dụng (history.listen)
  2. Theo dõi hiệu ứng (Effects)

I. Theo dõi sự thay đổi từ đường dẫn của ứng dụng:

Được sử dụng khi nào. Ví dụ trong trường hợp, ví dụ bạn cần xử lý là khi vào trang chi tiết sản phẩm với path là /product/id-san-pham thì sẽ fetch lấy dữ liệu chi tiết sản phẩm về, cập nhập lại vào state của product.

Ví dụ, mình có 1 state product có mã như bên dưới:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import * as productServices from '@/services/product';
 
export default {
  namespace: 'product',
 
  state: {
    currentProduct: {}
  },
 
  effects: {
    *fetchDetail({ productId }, { call, put }) {
      const response = yield call(productServices.fetchDetail, productId);
      yield put({
        type: 'saveDetail',
        data: response.data
      });
    }
  },
  reducers: {
    saveDetail(state, action) {
      return {
        ...state,
        currentProduct: action.data
      };
    }
  }
}

Trong model product của DvaJS, có hổ trợ cho mình đăng ký lắng nghe sự kiện từ subscriptions, nếu vào trang chi tiết sản phẩm, ứng với đường dẫn /product/product-id thì mình sẽ fetch dữ liệu chi tiết sản phẩm từ server về.

1
2
3
4
5
6
7
8
9
10
11
12
13
subscriptions: {
    listenFetchDetail({ dispatch, history }) {
      return history.listen(({ pathname }) => {
        const match = pathToRegexp('/product/:productId').exec(pathname);
        if (match) {
          dispatch({
            type: 'fetchDetail',
            productId: match[1]
          })
        }
      });
    }
  }

Ở đoạn mã trên, bằng cách tạo key và hàm trong subscriptions, chúng ta sẽ đăng ký lắng nghe sự thay đổi từ history, nếu pathname hiện tại là đường dẫn của chi tiết sản phẩm (product/product-id), thì sẽ fetch dữ liệu từ server về.

II. Theo dõi hiệu ứng (Effects):

Với cách này, chúng ta có thể làm được nhiều việc hơn là lắng nghe thay đổi từ pathname. Xét một kịch bản như sau:

Khi user login vào hệ thống, chúng ta sẽ lắng nghe, nếu đã login vào hệ thống và có thông tin user (effect là user/login/@@end), chúng ta sẽ yêu cầu lấy vị trí hiện tại của người dùng trên trình duyệt (Geolocation_API). Model user như sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import * as userServices from '@/services/user';
 
export default {
  namespace: 'user',
 
  state: {
    user: {},
    currentLocation: {}
  },
 
  effects: {
    *login({ username, password }, { call, put }) {
      const response = yield call(userServices.login, { username, password });
      if (response) {
        yield put({
          type: 'saveUser',
          data: response.data
        });
      }
    }
  },
  reducers: {
    saveUser(state, action) {
      return {
        ...state,
        user: action.data
      };
    },
    saveCurrentLocation(state, action) {
      return {
        ...state,
        currentLocation: action.data
      };
    }
  }
}

để lắng nghe Effects trong dvaJS, API cung cấp cho ta một khái niệm là watcher effect, ta khai báo thêm trong user model như sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import * as userServices from '@/services/user';
import { getGeoMe } from '@/utils/maps';
 
export default {
  namespace: 'user',
 
  state: {
    user: {},
    currentLocation: {}
  },
 
  effects: {
    *login({ username, password }, { call, put }) {
      const response = yield call(userServices.login, { username, password });
      if (response) {
        yield put({
          type: 'saveUser',
          data: response.data
        });
      }
    },
    loginWatcher: [
      function*({ take, select, call, put }) {
        while (true) {
          yield take('user/login/@@end');
          const currentLocation = yield call(getGeoMe);
          yield put({
            type: 'saveCurrentLocation',
            data: currentLocation.location
          });
        }
      },
      {
        type: 'watcher'
      }
    ]
  },
  reducers: {
    saveUser(state, action) {
      return {
        ...state,
        user: action.data
      };
    },
    saveCurrentLocation(state, action) {
      return {
        ...state,
        currentLocation: action.data
      };
    }
  }
}

Khác với việc sử dụng theo dõi từ thay đổi của pathname ứng dụng, thì theo dõi Effects chạy xuyên suốt trong ứng dụng, lúc ứng dụng được chạy và nạp model, mổi lần có effects login user được gọi và kết thúc thì nó sẽ bắt được effect này, có thể mới bắt đầu gọi tới login (user/login/@@start) hoặc đã login xong lưu dữ liệu user thành công (user/login/@@end). Trong trường hợp này ta cần bắt effect (user/login/@@end) vì lúc này user model mới có dữ liệu trong state.

Tags: dvaJSeffectsreactJSumiJS
Previous Post

Hướng dẫn Nginx #1: Các khái niệm cơ bản

Next Post

Phân biệt throttle và debounce

truongluu

truongluu

Next Post
Phân biệt throttle và debounce

Phân biệt throttle và debounce

Comments 2

  1. Pingback: Theo dõi action trong NuxtJS - Lưu Xuân Trường's Blog
  2. Pingback: Một số tips khi làm việc với dvaJS - Lưu Xuân Trường's Blog

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Never give up. Today is hard, tomorrow will be worse, but the day after tomorrow will be sunshine

Jack Ma

Quotations

About me

Field of interests: Svelte, ReactJS, Angular, VueJS, React Native, Flutter, NodeJS, MongoDB, Message Broker, WordPress, AdonisJS, NestJS, NuxtJS, Docker, Microservice, Arduino, Game HTML5. Hope to share my experiences with everybody

Recent Posts

  • Code push in React Native
  • What’s middleware? How does it work?
  • Styled components trong ReactJS
  • Frontity cơ bản phần I (Tạo và chạy dự án)
  • React framework for WordPress

Recent Comments

  • truongluu on Giới thiệu về UmiJS P2 (Cấu trúc thư mục, cấu hình thường dùng)
  • Hung on Giới thiệu về UmiJS P2 (Cấu trúc thư mục, cấu hình thường dùng)
  • Redux Saga phần III (Tips khi làm việc) - Lưu Xuân Trường's Blog on Quản lý trạng thái tải khi dùng redux-saga
  • Redux Saga phần II (Các khái niệm cơ bản) - Lưu Xuân Trường's Blog on Cheatsheets Non Blocking, Blocking Redux Saga
  • truongluu on Giới thiệu về UmiJS P4 (Server Side Rendering)

Archives

  • February 2021
  • January 2021
  • November 2020
  • October 2020
  • September 2020
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • March 2020
  • February 2020
  • January 2020
  • June 2019
  • May 2019
  • April 2019
  • March 2019
  • February 2019
  • January 2019
  • November 2018
  • October 2018
  • September 2018
  • August 2018
  • July 2018
  • April 2018
  • March 2018

Categories

  • AdonisJS
  • Angular
  • Arduino
  • Backend
  • Câu Hỏi Phỏng Vấn
  • CSS
  • Ebook
  • Frontend
  • Frontity
  • Góc Ngoài Lề
  • How to
  • IOS
  • IQ Test
  • Javascript
  • Kinh nghiệm
  • Kinh nghiệm làm việc
  • Máy chủ
  • Mobile
  • MongoDB
  • NestJS
  • NodeJS
  • NuxtJS
  • Plugins
  • React Native
  • React Native
  • ReactJS
  • Redis
  • Redux-Saga
  • RxJS
  • Tutorials
  • UmiJS
  • Uncategorized
  • VueJS
  • WordPress

Friends

Phu's blog
  • RxJS toàn tập (P1 giới thiệu RxJS là gì)

    RxJS toàn tập (P1 giới thiệu RxJS là gì)

    0 shares
    Share 0 Tweet 0
  • Giới thiệu về UmiJS P1 (Tổng quan về umiJS)

    0 shares
    Share 0 Tweet 0
  • Redux Saga phần I (Giới thiệu)

    0 shares
    Share 0 Tweet 0
  • Giới thiệu về UmiJS P2 (Cấu trúc thư mục, cấu hình thường dùng)

    0 shares
    Share 0 Tweet 0
  • Một số câu hỏi phỏng vấn frontend developer

    0 shares
    Share 0 Tweet 0

About me

Lưu Xuân Trường

Field of interests: Svelte, ReactJS, Angular, VueJS, React Native, Flutter, NodeJS, MongoDB, Message Broker, WordPress, AdonisJS, NestJS, NuxtJS, Docker, Microservice, Arduino, Game HTML5. Hope to share my experiences with everybody

© 2020 https://luuxuantruong.info

No Result
View All Result
  • Trang chủ
  • Backend
    • Laravel
    • Golang
    • NodeJS
    • MongoDB
    • Redis
    • WordPress
      • Kinh nghiệm
      • Plugins
  • Frontend
    • CSS
    • Javascript
      • ReactJS
      • UmiJS
      • VueJS
      • NuxtJS
      • Angular
      • RxJS
    • Game HTML5
  • Mobile
    • React Native
    • IOS
    • Android
    • Flutter
  • Tutorials
    • Redux-Saga
  • How to
  • Góc Ngoài Lề
    • Sống Chậm Nghĩ Sâu
    • Câu Hỏi Phỏng Vấn
    • IQ Test
  • Liên Hệ

© 2020 https://luuxuantruong.info

Welcome Back!

Login to your account below

Forgotten Password?

Create New Account!

Fill the forms below to register

All fields are required. Log In

Retrieve your password

Please enter your username or email address to reset your password.

Log In