为了深入理解 Redux 状态管理工具,手写一个简化的(也是作业)
手写一个类似 Redux 的 createStore,实现一个简单的列表增删。
输入名称,序号自增并以此名称添加进列表;输入要删除的序号,就删除对应序号的行
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <!DOCTYPE html> <html lang="cn"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>redux</title> </head> <body> <div class="add"> <input type="text" placeholder="输入名称" /> <button>添加</button> </div> <div class="delete"> <input type="text" placeholder="输入要删除的id" /> <button>删除</button> </div> <div class="show"></div> <script src="./main.js"></script> </body> </html>
|
main.js
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
| const addTextDOM = document.querySelector('.add input'); const addBtnDOM = document.querySelector('.add button'); const deleteTextDOM = document.querySelector('.delete input'); const deleteBtnDOM = document.querySelector('.delete button'); const showDOM = document.querySelector('.show');
function createStore(reducer) { let state = reducer(undefined, {}); const listeners = [];
const getState = () => state; const dispatch = (action) => { state = reducer(state, action); listeners.forEach((listener) => listener()); }; const subscribe = (listener) => { listeners.push(listener);
return () => { const index = listeners.indexOf(listener); listeners.splice(index, 1); }; };
return { getState, dispatch, subscribe }; }
function reducer(state = { id: 0, names: [] }, action) { switch (action.type) { case 'ADD': return { id: state.id + 1, names: [...state.names, { id: state.id, name: action.name }], }; case 'DELETE': return { ...state, names: state.names.filter((item) => item.id !== action.id), }; default: return state; } }
const store = createStore(reducer);
function render() { const currentState = store.getState(); showDOM.innerHTML = currentState.names.map((item) => `<p>序号:${item.id},名称:${item.name}</p>`).join(''); }
const unRender = store.subscribe(render);
addBtnDOM.addEventListener('click', () => { const name = addTextDOM.value; store.dispatch({ type: 'ADD', name }); addTextDOM.value = ''; }); deleteBtnDOM.addEventListener('click', () => { const id = Number(deleteTextDOM.value); store.dispatch({ type: 'DELETE', id }); deleteTextDOM.value = ''; });
|