React boilerplate data flow
React boilerplate là một ứng dụng React đã được cài đặt tích hợp sẵn redux-saga, thuận tiện cho việc phát triển. Chúng ta cùng xem xét luồng dữ liệu, cách tạo component, container trong ứng dụng này nhé :D
Tạo container
Khi muốn tạo 1 component mới để thực hiện chức năng, bạn có thể thực hiện bằng cách dùng lệnh
1 | npm run generate container |
(Nó sẽ tạo đủ các thư mục redux, saga, constant, selector, action và kết nối saga cho bạn).
Đăng ký Component này trong router để hoạt động nào
1 | /* containers/App/index.js */ |
Props
Khi xử lý các sự kiện (như click button, bắt sự kiện thay đổi 1 field nào đó) để bắn ra các action tới saga, reducer, bạn cần sử dụng nó như các props
để dispatch
được sự kiện (trong ví dụ là click button)
Đăng kí nó vào đầu vào component
1 | export function JestExample({ user, onClickButton }) { |
và đăng ký mapDispatchToProps
để dispatch sự kiện
1 | function mapDispatchToProps(dispatch) { |
Chỗ này bạn có thể tùy chọn bắn action có qua saga hay không (saga là middleware, nếu cần call API hay làm 1 việc gì đó như truyền thêm dữ liệu thì hãy dùng saga) nếu không có thể truyền thẳng tới reducer.
Quyết định có qua saga hay không chính là do type của action loadUser bạn truyền vào (có type
đã được đăng ký ở saga hay không?)
Action có dạng
1 | export function loadUser() { |
Xử lý saga (tùy chọn)
Nếu action của bạn có chuyển qua saga, chúng ta sẽ mở file saga để xử lý.
Bạn cần đăng ký saga và call API, sau đó truyền action mới tới reducer thôi, khá đơn giản:
1 | import { call, put, select, takeLatest } from 'redux-saga/effects'; |
Reducer
Sau khi bên view phát action, reducer sẽ đón nhận và xử lý. Trong reducer sẽ có
- initState: state mặc định trong store
- Hàm xử lý action:
initState ======> (dữ liệu từ người dùng truyền xuống hoặc lấy được từ saga) ====> newState trả ngược về view
Render state mới ra view
Sau khi đã có state mới trả về từ reducer. công việc cuối cùng là render state mới ra view.
Ta sẽ ánh xạ state này thành props của Component để hiển thị. Nó sẽ được thực hiện qua hàm mapStateToProps trong Component.
Chúng ta sẽ sử dụng selector để thực hiện việc ánh xạ này:
1 | import { createSelector } from 'reselect'; |
File index.js
1 | const mapStateToProps = createStructuredSelector({ |
OK thế là state user được chuyển thành props với tên user trong Component rồi đó.
Tóm lại luồng dữ liệu sẽ như sau
View
: dispatch action (dưới dạng props và được đăng kí trong mapDispatchToProps) ======> Saga
(tùy chọn): nhận action từ view, call API và bắn 1 action mới tới reducer qua phương thức put ====> Reducer
: xử lý với mỗi action và dữ liệu qua switch/case, trả về new State từ initState ======> View
: nhận newState, map nó thành props và render ra view (mapStateToProps)
Action sẽ có dạng
1 | { |
React boilerplate data flow