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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Demo app Count with use ReactJS and Redux</title> </head> <body> <div id="root"></div> <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.1.0/redux.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.4/react-redux.js"></script> <script src="https://cdn.jsdelivr.net/npm/@reduxjs/[email protected]/dist/redux-toolkit.umd.min.js"></script> <!-- =========== slices/count_slice.js =========== --> <script> //1. Khai báo Slice: Dùng RTK.createSlice khai báo tất cả State, Reducers và Actions luôn const countSlice = RTK.createSlice({ name: 'count', initialState: { amount: 1 }, reducers: { action_increment(state, action) { state.amount += action.payload.amount; }, action_decrement(state, action) { state.amount -= action.payload.amount; }, } }); // Export ra các actions, reducer tương ứng :D const { action_increment, action_decrement } = countSlice.actions; const countReducer = countSlice.reducer; </script> <!-- =========== src/api/count.js =========== --> <script> // Important: Middleware: Các action dạng bất đồng bộ thì sẽ xử lý tại đây // TH này, giải quyết middleware bằng "redux-thunk" (đã tự động cài ở RTK) // Tại button, ta dispatch 1 function có dạng trả về là 1 async function // async function này có nhiệm vụ giải quyết các promise, sau đó mới dispatch action thật const increment_async = (payload) => async (dispatch) => { let promise = (data) => new Promise((resolve, reject) => { setTimeout(() => { resolve(data); }, 1000); }) let response = await promise(payload); dispatch(action_increment(response)); } </script> <!-- =========== src/store.js =========== --> <script type="text/babel"> //2. Khai báo store bằng "configureStore": tất cả các Reducer trong store ở dưới đây //configureStore: mặc định đã có "thunk" const store = RTK.configureStore({ reducer: { count: countReducer } }) </script> <!-- =========== components/App.js =========== --> <script type="text/babel"> function App(props) { //3. Dùng useSelector và useDispatch để làm việc với store của Redux const count = ReactRedux.useSelector(state => state.count); const dispatch = ReactRedux.useDispatch(); return ( <div> <p>{count.amount}</p> <button onClick={() => { dispatch(action_increment({ amount: 1 })) }}>Increase</button> <button onClick={() => { dispatch(action_decrement({ amount: 1 })) }}>Decrease</button><br /> <button onClick={() => { dispatch(increment_async({ amount: 1 })) }}>Increase Async</button> </div> ) } </script> <!-- =========== src/index.js =========== --> <script type="text/babel"> //4. Connect React và Redux bằng Provider, với store=store đã được khai báo ở trên const Provider = ReactRedux.Provider; ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') ); </script> </body> </html> |
Demo-Count: 7. use Redux-Toolkit, Thunk middleware
Author: admin - Posted: 28/06/21 - Update: 28/06/21