- Sử dụng khi một component có rất nhiều state.
- Các state này nếu cùng thay đổi trạng thái vào 1 thời điểm thì chỉ cần 1 lần render duy nhất
- Mô hình này quản lý giống hệt Redux
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 |
<!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>ReactJS</title> </head> <body> <div id="app"></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 type="text/babel"> const { useReducer } = React; //1. Khai báo state const initialState = { now: 0, loading: false } //2. Khai báo Reducer const nowReducer = (state = initialState, action) => { switch (action.type) { case 'FETCH_INIT': { return { ...state, loading: true, now: 'Loading...', } } case 'FETCH_SUCCESS': { return { ...state, loading: false, now: action.payload, } } case 'FETCH_FAILURE': { return { ...state, loading: false, now: "Error !!!", } } default: return state; } } //3. Khai báo action const action_init = () => ({ type: 'FETCH_INIT', }) const action_success = (now) => ({ type: 'FETCH_SUCCESS', payload: now, }) const action_failure = (now) => ({ type: 'FETCH_FAILURE', payload: now, }) //4. Sử dụng tại Componet => dùng useReducer để lấy state, và dùng dispatch để action function App(props) { const [state, dispatch] = useReducer(nowReducer, initialState) const fakePromise = () => new Promise((resolve, reject) => { setTimeout(() => { let now = (new Date()).getTime(); if (now % 2) resolve(now); else reject(now); }, 500); }) const getTime = () => { dispatch(action_init()) fakePromise() .then(res => dispatch(action_success(res))) .catch(err => dispatch(action_failure(err))) } return ( <div> <p>{state.now}{state.loading && <img src="https://vcdn-ione.vnecdn.net/2016/07/13/loading-256-0001-4566-1468383063.gif" width="12px" />}</p> <button onClick={getTime}>Get Time</button> </div> ) } ReactDOM.render( <App />, document.getElementById('app') ); </script> </body> </html> |