1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- <header>reducers auth</header>
- <body>
- <div id="testDiv">
- Test
- </div>
- <script>
- function jwtDecode(token) { // расщифровки токена авторизации
- if (!token || typeof token != "string")
- return undefined;
- let tokenArr = token.split(".");
- if (tokenArr.length != 3)
- return undefined;
- try {
- let tokenJsonStr = atob(tokenArr[1]);
- let tokenJson = JSON.parse(tokenJsonStr);
- return tokenJson;
- }
- catch {
- return undefined;
- }
- }
- function authReducer(state = {}, action) { // диспетчер обработки login
- if (action) {
- if (action.type === 'AUTH_LOGIN') {
- let newState = { ...state };
- newState.token = action.token;
- newState.payload = jwtDecode(action.token);
- if (!newState.payload) {
- newState.token = undefined;
- }
- return newState;
- }
- else if (action.type === 'AUTH_LOGOUT') {
- let newState = { ...state };
- newState.token = undefined;
- newState.payload = undefined;
- return newState;
- }
- }
- return state;
- }
- function createStore(reducer) {
- let state = reducer(undefined, {}) //стартовая инициализация состояния, запуск редьюсера со state === undefined
- let cbs = [] //массив подписчиков
- const getState = () => state //функция, возвращающая переменную из замыкания
- const subscribe = cb => (cbs.push(cb), //запоминаем подписчиков в массиве
- () => cbs = cbs.filter(c => c !== cb)) //возвращаем функцию unsubscribe, которая удаляет подписчика из списка
- function dispatch(action) {
- if (typeof action === 'function') { //если action - не объект, а функция
- return action(dispatch, getState) //запускаем эту функцию и даем ей dispatch и getState для работы
- }
- const newState = reducer(state, action) //пробуем запустить редьюсер
- if (newState !== state) { //проверяем, смог ли редьюсер обработать action
- state = newState //если смог, то обновляем state
- for (let cb of cbs) cb() //и запускаем подписчиков
- }
- }
- return {
- getState, //добавление функции getState в результирующий объект
- dispatch,
- subscribe //добавление subscribe в объект
- }
- }
- function actionPromise(promise) {
- return async function Exec(dispatch) {
- try {
- const payload = await promise //ожидаем промиса;
- dispatch(actionAuthLogin(payload)); //сигнализируем redux, что промис успешно выполнен
- return payload //в месте запуска store.dispatch с этим thunk можно так же получить результат промиса
- }
- catch (error) {
- dispatch(actionLogOut()) //в случае ошибки - сигнализируем redux, что промис несложился
- }
- };
- }
- const actionAuthLogin = token => ({ type: 'AUTH_LOGIN', token });
- const actionAuthLogout = () => ({ type: 'AUTH_LOGOUT' });
- const store = createStore(authReducer)
- store.subscribe(() => {
- console.log(store.getState())
- });
- const token =
- "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOnsiaWQiOiI2Mzc3ZTEzM2I3NGUxZjVmMmVjMWMxMjUiLCJsb2dpbiI6InRlc3Q1IiwiYWNsIjpbIjYzNzdlMTMzYjc0ZTFmNWYyZWMxYzEyNSIsInVzZXIiXX0sImlhdCI6MTY2ODgxMjQ1OH0.t1eQlRwkcP7v9JxUPMo3dcGKprH-uy8ujukNI7xE3A0"
- store.dispatch(actionAuthLogin(token));
- store.dispatch(actionAuthLogout());
- </script>
- </body>
|