最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React配置Redux并結(jié)合本地存儲(chǔ)設(shè)置token方式

 更新時(shí)間:2024年01月25日 09:38:47   作者:sonicwater  
這篇文章主要介紹了React配置Redux并結(jié)合本地存儲(chǔ)設(shè)置token方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

React 項(xiàng)目使用 TypeScriptHooks API,本文介紹配置 Redux 并結(jié)合本地存儲(chǔ)設(shè)置 token

安裝依賴

yarn add redux -S
yarn add react-redux -S
  • redux 可以脫離 react 使用, react-redux 的作用主要是提供 <Provider> 標(biāo)簽包裹頁(yè)面組件。

store 目錄,以加減運(yùn)算為例

src
 ├── store
 │     ├── actions
 │     │    └── counter.ts
 │     ├── reducers
 │     │    ├── counter.ts
 │     │    └── index.ts
 │     └── index.ts

./src/store/index.ts

import { createStore } from 'redux';
import allReducers from './reducers';
// 注冊(cè)
const store = createStore(
  allReducers,
  // @ts-ignore
  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() // 引入Redux調(diào)試工具
);
// 導(dǎo)出
export default store;

./src/store/actions/counter.ts

export interface action {
  type: 'INCREMENT' | 'DECREMENT';
  num?: number;
}
export const increment = (num: number = 1): action => ({
  type: 'INCREMENT',
  num
});
export const decrement = (num: number = 1): action => ({
  type: 'DECREMENT',
  num
});

./src/store/reducers/index.ts

import { combineReducers } from "redux";
import counter from "./counter";
// 整合
const allReducers = combineReducers({ counter });
export default allReducers;

./src/store/reducers/counter.ts

interface action {
  type: "INCREMENT" | "DECREMENT";
  num?: number;
}
const counter = (state = 0, action: action) => {
  switch (action.type) {
    case "INCREMENT":
      return state + (action.num as number);
    case "DECREMENT":
      return state - (action.num as number);
    default:
      return state;
  }
};
export default counter;

再看 ./src/app.tsx

import { FC } from 'react';
import { Provider } from 'react-redux';
import store from 'src/store';
...
const App: FC = () => {
  return (
    <Provider store={store}>
      ...
    </Provider>
  );
}
  • 只列出和 react-redux、store 有關(guān)的代碼。
  • <Provider> 放在最外層,里面放路由組件。

用一個(gè)組件頁(yè)面 CounterComponent 測(cè)試 store 中的 counter 模塊。

import { FC } from 'react';
import { Button } from 'antd';
import { useDispatch, useSelector } from 'react-redux';
import { increment, decrement } from "src/store/actions/counter";

const CounterComponent: FC = () => {
  const dispatch = useDispatch();
  const num = useSelector(state => (state as any).counter);
  return(
  	<>
  	  <div className="text-blue-500">
        { num }
      </div>
      <Button type="default" onClick={() => dispatch(decrement())}>-1</Button>
      <Button type="primary" onClick={() => dispatch(increment())}>+1</Button>
  	</>
  )
}

export default CounterComponent;
  • 注意 react-redux 提供的 useDispatch、useSelector 兩個(gè) Hooks 的使用。
...
return(
  <>
	<div className="text-blue-500">
	  { num }
	</div>
	<Button type="default" onClick={() => dispatch({
	  type: 'DECREMENT',
	  num: 1
	})}>-1</Button>
	<Button type="primary" onClick={() => dispatch({
	  type: 'INCREMENT',
	  num: 1
	})}>+1</Button>
  </>
)
...
  • dispatch 也可以像上面這樣寫,如此可以省略 src/store/actions/counter 相關(guān)方法的引入。
const num = useSelector(state => (state as any).counter);
  • useSelector 可以訪問并返回全部 store 中的子模塊,這里只返回 counter 子模塊。

可以參照上面例子寫一個(gè)保存登錄 login_token 的子模塊,并結(jié)合 localStorage 根據(jù)登錄狀態(tài)控制頁(yè)面跳轉(zhuǎn)。

至于已經(jīng)有 redux 為什么還要結(jié)合 localStorage ,這樣的疑問,有兩點(diǎn)原因:

  • redux 在頁(yè)面刷新后值會(huì)被初始化,無(wú)法實(shí)現(xiàn)數(shù)據(jù)持久化。但是 redux 的數(shù)據(jù)可以影響子路由頁(yè)面響應(yīng)式變化。
  • localStorage 保存的數(shù)據(jù)不會(huì)被刷新等操作影響,可以持久化。但是 localStorage 不具備 redux 的響應(yīng)式變化功能。

redux 中創(chuàng)建用戶模塊 user 里面保存 login_token。

注意: 這里的 login_token 是調(diào)登錄接口返回的經(jīng)過加密的 32 位字符串,不是 JWT 標(biāo)準(zhǔn)格式的 token

修改一下目錄,增加 user 相關(guān)文件。

src
 ├── store
 │     ├── actions
 │     │    ├── counter.ts
 │     │    └── user.ts
 │     ├── reducers
 │     │    ├── counter.ts
 │     │    ├── index.ts
 │     │    └── user.ts
 │     └── index.ts

./src/store/actions/user

export interface action {
  type: "SET_TOKEN" | "DELETE_TOKEN";
  login_token?: string;
}
export const setToken = (login_token: string): action => ({
  type: "SET_TOKEN",
  login_token
});
export const deleteToken = (): action => ({
  type: "DELETE_TOKEN"
});

./src/store/reducers/user

interface action {
  type: "SET_TOKEN" | "DELETE_TOKEN";
  token?: string;
}
const user = ( state='', action: action ) => {
  switch (action.type) {
    case "SET_TOKEN":
      state = action.token as string;
      localStorage.setItem('login_token', state);
      break
    case "DELETE_TOKEN":
      localStorage.removeItem('login_token');
      state = '';
      break
    default:
      state = localStorage.getItem('login_token') || '';
      break
  }
  return state;
};
export default user;
  • 所有對(duì) login_token 的設(shè)置、獲取、刪除都先對(duì)本地存儲(chǔ)進(jìn)行響應(yīng)操作,然后返回值。

修改 ./src/store/reducers/index.ts

import { combineReducers } from "redux";
import counter from "./counter";
import user from "./user";
// 整合
const allReducers = combineReducers({ counter, user });
export default allReducers;

頁(yè)面相關(guān)操作

登錄:

import { useDispatch } from 'react-redux';
import { setToken } from "src/store/actions/user";
import { useHistory } from 'react-router-dom';

interface LoginEntity {
  username: string;
  password: string;
}

const Login = () => {
  const dispatch = useDispatch();
  const history = useHistory();
  ...
  // 登陸按鈕邏輯
  const handleLogin = async (login:LoginEntity) => {
    // 調(diào)用登陸Api,獲取結(jié)果
    let res = await doLogin({...login});
	dispatch(setToken(res.data.login_token));
	// 跳轉(zhuǎn)到 home 頁(yè)面
	history.push('/home');
  }
  ...
}
  • 在驗(yàn)證登錄信息后,調(diào)用登錄接口,接口返回 login_token
  • dispatch(setToken(res.data.login_token)) 方法存儲(chǔ)到 redux 中并頁(yè)面跳轉(zhuǎn)。

登出的邏輯:

  ...
    dispatch(deleteToken());
    history.push('/login');
  ...

useDispatch 屬于 Hooks API ,它只能被用在函數(shù)式組件中。

如果要在一些配置文件如 API 接口的配置文件中使用,需要換一種寫法。

...
import store from "src/store";
// axios實(shí)例攔截請(qǐng)求
axios.interceptors.request.use(
  (config: AxiosRequestConfig) => {
    ...
    Object.assign(config['post'], {
      login_token: store.getState().user
    });
    ...
    return config;
  },
  (error:any) => {
    return Promise.reject(error);
  }
)
...
  • 在調(diào)接口前攔截請(qǐng)求,在請(qǐng)求參數(shù)中添加 login_token
  • 注意寫法:store.getState() 后面接的是模塊名

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 使用React Native創(chuàng)建以太坊錢包實(shí)現(xiàn)轉(zhuǎn)賬等功能

    使用React Native創(chuàng)建以太坊錢包實(shí)現(xiàn)轉(zhuǎn)賬等功能

    這篇文章主要介紹了使用React Native創(chuàng)建以太坊錢包,實(shí)現(xiàn)轉(zhuǎn)賬等功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-07-07
  • React中的Refs屬性你來(lái)了解嗎

    React中的Refs屬性你來(lái)了解嗎

    這篇文章主要為大家詳細(xì)介紹了的React?Refs屬性,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • react中路由跳轉(zhuǎn)及傳參的實(shí)現(xiàn)

    react中路由跳轉(zhuǎn)及傳參的實(shí)現(xiàn)

    本文主要介紹了react中路由跳轉(zhuǎn)及傳參的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • React-Native TextInput組件詳解及實(shí)例代碼

    React-Native TextInput組件詳解及實(shí)例代碼

    這篇文章主要介紹了React-Native TextInput組件詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • React中的useEffect useLayoutEffect到底怎么用

    React中的useEffect useLayoutEffect到底怎么用

    這篇文章主要介紹了React中的useEffect useLayoutEffect具體使用方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-02-02
  • react腳手架如何配置less和ant按需加載的方法步驟

    react腳手架如何配置less和ant按需加載的方法步驟

    這篇文章主要介紹了react腳手架如何配置less和ant按需加載的方法步驟,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧
    2018-11-11
  • 詳解create-react-app 自定義 eslint 配置

    詳解create-react-app 自定義 eslint 配置

    這篇文章主要介紹了詳解create-react-app 自定義 eslint 配置,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧
    2018-06-06
  • react中使用forEach或map兩種方式遍歷數(shù)組

    react中使用forEach或map兩種方式遍歷數(shù)組

    這篇文章主要介紹了react中使用forEach或map兩種方式遍歷數(shù)組,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • React 中合成事件的實(shí)現(xiàn)示例

    React 中合成事件的實(shí)現(xiàn)示例

    本文主要介紹了React 中合成事件的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-02-02
  • 詳解webpack + react + react-router 如何實(shí)現(xiàn)懶加載

    詳解webpack + react + react-router 如何實(shí)現(xiàn)懶加載

    這篇文章主要介紹了詳解webpack + react + react-router 如何實(shí)現(xiàn)懶加載,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-11-11

最新評(píng)論

景宁| 灵台县| 民县| 翁牛特旗| 黄山市| 常德市| 朝阳区| 蓝山县| 静宁县| 贵州省| 安塞县| 汪清县| 临朐县| 额尔古纳市| 旬阳县| 东光县| 锡林浩特市| 成安县| 南宫市| 资兴市| 鸡东县| 奉新县| 德惠市| 焉耆| 岐山县| 扎兰屯市| 会东县| 张家川| 南康市| 桓仁| 丹棱县| 郑州市| 石渠县| 新竹县| 赤壁市| 卢湾区| 夏邑县| 新绛县| 祁阳县| 六枝特区| 盐津县|