Học React/Redux qua ví dụ thực tế: Authentication thông qua Soundcloud API

Trong bài trước chúng ta đã thực hiện việc cài đặt react-router để phục vụ cho việc authentication thông qua SoundCloud API.

Trong bài hôm nay chúng ta sẽ thực hiện chuyện làm thế nào để user của SoundCloud có thể login được thông qua SoundCloud API.

Authentication

Để authenticate user chúng ta cần setup một action để trigger việc authenticate. Cùng expose ra function để làm việc này nào.

Tạo file src/actions/auth.js, sau đó vào file src/actions/index.js sửa lại như sau.

Tiếp tục mở file src/actions/auth.js.

Ở đây chúng ta tạm thời log ra kết quả của API trả về để kiểm tra chắc chắn mọi việc đang hoạt động đúng.

Tuy nhiên, hiện giờ chưa có cái gì trigger action này cả, đặt đâu bây giờ nhỉ, à thôi đặt đại vào TrackList đã, sau này tính tiếp.

Mở src/components/TrackList/index.js.

Như hôm trước mình đã nói về decorator @connect, chúng ta có param đầu tiên là hàm mapStateToProps, giờ chúng ta có param thứ hai đó là mapDispatchToProps hàm này trả về một object chứa những function. Hay có thể implement một cách tường minh như thế này.

Giờ thì chúng ta sẽ bind những action này với presenter để dispatch function.

Mở src/components/TrackList/TrackList.js.

Rồi bây giờ thử start app lên nào.

CLIENT_ID=xxx npm start

Ồ có vẻ ngon lành, nhấn Login thử xem nào.

Ops, bị lỗi kìa, nó require client_id, ủa mà chúng ta truyền vào rồi mà nhỉ? Vậy thì sai ở đâu?

Take a step back, chúng ta có CLIENT_ID lấy từ file config.js, trong này thì nó lấy từ process.env.CLIENT_ID, hmm, dường như có điều gì đó không đúng ở đây.

À, chúng ta build app bằng webpack, vậy chắc chắn lúc build webpack đang không đọc được environment variable để set vào source code rồi. Dùng google thần chưởng nào.

Chúng ta có webpack.DefinePlugin để set environment variable khi chạy webpack nè. Setting đơn giản thôi.

Mở file webpack.config.js. Trong phần plugin thêm DefinePlugin vào như sau.

Trong file config.js sửa lại thành.

Thật ra thì các bạn có thể hoàn toàn sử dụng bằng __CLIENT_ID__ trong source thay vì set lại vào trong file config.js như mình. Mình làm màu đấy. Keke.

Ok start app một lần nữa nào.

Mọi thứ ngon lành rồi đúng không? Nhấn login, nó sẽ hiện ra popup, đăng nhập account SoundCloud của các bạn vào, các bạn có thấy console log ra thông tin user của bạn không? Nếu có thì các bạn đã thành công rồi đấy.

Sao vẫn chưa được đúng không, tôi biết mà, chúng ta đã nhầm một bước đó là trong Callback.js, chúng ta call opener.SoundCloud, tuy nhiên khi library soundcloud init xong nó sẽ tạo ra object SC thay vì SoundCloud, chỉ cần sửa lại thành opener.SC là sẽ ổn. Nào thử lại một lần nữa!

Được rồi đúng không nào!

Screen Shot 2016-12-25 at 10.56.38 PM.png
Kết quả nè!

Tiếp theo, chúng ta đang sử dụng fetch để call API. Nhưng chúng ta cần phải polyfill nó vì không phải browser nào cũng support fetch API ở thời điểm hiện tại.

Chúng ta sẽ sử dụng whatwg-fetch.

npm --save install whatwg-fetch
npm --save-dev install imports-loader exports-loader

Update webpack.config.js như sau.

Redux Thunk

Bước tiếp theo, sau khi đã có được data từ SoundCloud API chúng ta sẽ phải làm gì đây?

Chúng ta sẽ phải store đống data đó ở đâu đó, hơn nữa, chúng ta đang viết một asynchronous action đầu tiên của cuộc đời, tại sao? vì chúng ta sẽ phải đợi SoundCloud server trả về dữ liệu trước khi thực hiện bước tiếp theo, và những tác vụ như thế ta gọi à asynchronous vì engine sẽ bốc nó ra một chỗ khác cho thằng khác làm, khi nào nó làm xong thì nó quăng trả lại trong cái thứ ta gọi là callback, đó là một cách hiểu đơn giản nhất, thông tin chi tiết chắc các bạn phải Google thêm rồi.

Với redux, chúng ta có hàng tá middleware để deal với các async actions như là redux thunk, redux promise, redux saga, redux observable, … Trong series này mình sẽ sử dụng redux thunk, chắc hẳn các bạn sẽ hỏi tại sao? Tại vì mình thấy nó đơn giản nhất, thế thôi.

Thunk middleware trả về một function thay vì một action, khi sử dụng async call, chúng ta có thể hoãn việc dispatch function với middleware này. Hơn nữa, inner function sẽ cho phép chúng ta access vào store cũng như là getState.

npm --save install redux-thunk

Sau đó chúng ta apply middleware này trong store config.

Mở file src/store.js.

Bây giờ chúng ta đã sẵn sàng mọi thứ, cần phải tạo thêm 1 set gồm action type, action creator, và reducer nữa.

Mở constant.js. Thêm action type ME_SET.

Mở src/actions/auth.js.

Thay vì console log, chúng ta sẽ gọi action creator.

Tiếp theo, cùng tạo reducer src/reducers/auth.js.

Nhớ thêm vào root reducer nhé, mở file src/reducers/index.js.

Sau khi đã có thông tin user, chúng ta sẽ phải xử lý để ẩn nút Login đi.

Mở src/component/TrackList/index.js. Connect component với reducer auth.

Chỉnh sửa lại presenter. Mở src/components/TrackList/TrackList.js.

Ok, test lại một lần nữa nào!

Screen Shot 2016-12-25 at 11.51.22 PM.png
Đã set được user vào store!

Series hướng dẫn React/Redux đã gần đi đến hồi kết, chỉ cần hai bài nữa là chúng ta sẽ hoàn thành 100% nội dung.

Trong hai bài cuối cùng, chúng ta sẽ cũng tìm hiểu cách hiển thị list track của user và cuối cùng là làm thế nào để play track trên browser.

Source code trong bài các bạn có thể tìm thấy ở https://github.com/codeaholicguy/react-redux-tutorial/tree/master/authentication-with-soundcloud

Hẹn gặp lại các bạn vào thứ tư tuần sau! Nếu các bạn thấy bài viết của mình hay và có ích, đừng quên share nó cho bạn bè nhé! À mà nhớ like luôn fanpage bên tay phải nhé, trên fanpage mình có làm một series truyện hài hước dành cho developer đấy!

Thân ái!

 

Advertisements

2 thoughts on “Học React/Redux qua ví dụ thực tế: Authentication thông qua Soundcloud API

Bình luận

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Đăng xuất / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Đăng xuất / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Đăng xuất / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Đăng xuất / Thay đổi )

Connecting to %s