DvaJS構(gòu)建配置React項目與使用

1.1,介紹

dva 首先是一個基于 redux 和 redux-saga 的數(shù)據(jù)流方案,然后為了簡化開發(fā)體驗,dva 還額外內(nèi)置了 react-router 和 fetch,所以dva是基于現(xiàn)有應(yīng)用架構(gòu) (redux + react-router + redux-saga 等)的一層輕量封裝。是由阿里架構(gòu)師 sorrycc 帶領(lǐng) team 完成的一套前端框架。

1.2,需求

快速搭建基于react的項目(PC端,移動端)。

二,DvaJS構(gòu)建項目

2.1,初始化項目

第一步:安裝node

第二步:安裝最新版本dva-cli

1 $ npm install dva-cli -g

2 $ dva -v

第三步:dva new 創(chuàng)建新應(yīng)用

1 $ dva new myapp

也可以在創(chuàng)建項目目錄myapp后,用dva init初始化項目

1 $ dva init

第四步:運行項目

1 $ cd myapp

2 $ npm start

瀏覽器會自動打開一個窗口

2.2,項目架構(gòu)介紹

|-mock? ? ? ? ? ? //存放用于 mock 數(shù)據(jù)的文件

|-node_modules? ? ? ? ? ? //項目包

|-public? ? ? ? ? ? //一般用于存放靜態(tài)文件,打包時會被直接復(fù)制到輸出目錄(./dist)

|-src? ? ? ? ? ? ? //項目源代碼

? |? |-asserts? ? ? ? //用于存放靜態(tài)資源,打包時會經(jīng)過 webpack 處理

? |? |-caches? ? ? ? //緩存

? |? |-components? ? //組件 存放 React 組件,一般是該項目公用的無狀態(tài)組件

? |? |-entries? ? ? ? //入口

? |? |-models? ? ? ? //數(shù)據(jù)模型 存放模型文件

? |? |-pages? ? ? ? ? //頁面視圖

? |? |-routes? ? ? ? //路由 存放需要 connect model 的路由組件

? |? |-services? ? ? //服務(wù) 存放服務(wù)文件,一般是網(wǎng)絡(luò)請求等

? |? |-test? ? ? ? ? //測試

? |? |-utils? ? ? ? ? //輔助工具 工具類庫

|-package.json? ? ? //包管理代碼

|-webpackrc.js? //開發(fā)配置

|-tsconfig.json? ? /// ts配置

|-webpack.config.js //webpack配置

|-.gitignore //Git忽略文件

在dva項目目錄中主要分3層,models,services,components,其中models是最重要概念,這里放的是各種數(shù)據(jù),與數(shù)據(jù)交互的應(yīng)該都是在這里。services是請求后臺接口的方法。components是組件了。

三,DvaJS的使用

3.1,DvaJS的五個Api

復(fù)制代碼

1 import dva from 'dva';

2 import {message} from 'antd';

3 import './index.css';

4

5 // 1. Initialize 創(chuàng)建 dva 應(yīng)用實例

6 const app = dva();

7

8 // 2. Plugins 裝載插件(可選)

9 app.use({

10? onError: function (error, action) {

11? ? message.error(error.message || '失敗', 5);

12? }

13 });

14

15 // 3. Model 注冊model

16? app.model(require('../models/example').default);

17

18 // 4. Router 配置路由

19 app.router(require('../routes/router').default);

20

21 // 5. Start 啟動應(yīng)用

22 app.start('#root');

23

24 export default app._store; // eslint-disable-line 拋出

復(fù)制代碼

1,app = dva(Opts):創(chuàng)建應(yīng)用,返回 dva 實例。(注:dva 支持多實例)?

在opts可以配置所有的hooks

復(fù)制代碼

1 const app = dva({

2? ? ? history,

3? ? ? initialState,

4? ? ? onError,

5? ? ? onHmr,

6 });

復(fù)制代碼

這里比較常用的是,history的配置,一般默認的是hashHistory,如果要配置 history 為 browserHistory,可以這樣:

1 import dva from 'dva';

2 import createHistory from 'history/createBrowserHistory';

3 const app = dva({

4? history: createHistory(),

5 });

initialState:指定初始數(shù)據(jù),優(yōu)先級高于 model 中的 state,默認是 {},但是基本上都在modal里面設(shè)置相應(yīng)的state。

2,app.use(Hooks):配置 hooks 或者注冊插件。

1 app.use({

2? onError: function (error, action) {

3? ? message.error(error.message || '失敗', 5);

4? }

5 });

可以根據(jù)自己的需要來選擇注冊相應(yīng)的插件

3,app.model(ModelObject):這里是數(shù)據(jù)邏輯處理,數(shù)據(jù)流動的地方。

復(fù)制代碼

1 export default {

2

3? namespace: 'example',//model 的命名空間,同時也是他在全局 state 上的屬性,只能用字符串,我們發(fā)送在發(fā)送 action 到相應(yīng)的 reducer 時,就會需要用到 namespace

4

5? state: {},//表示 Model 的狀態(tài)數(shù)據(jù),通常表現(xiàn)為一個 javascript 對象(當(dāng)然它可以是任何值)

6

7? subscriptions: {//語義是訂閱,用于訂閱一個數(shù)據(jù)源,然后根據(jù)條件 dispatch 需要的 action

8? ? setup({ dispatch, history }) {? // eslint-disable-line

9? ? },

10? },

11

12? effects: {//Effect 被稱為副作用,最常見的就是異步操作

13? ? *fetch({ payload }, { call, put }) {? // eslint-disable-line

14? ? ? yield put({ type: 'save' });

15? ? },

16? },

17

18? reducers: {//reducers 聚合積累的結(jié)果是當(dāng)前 model 的 state 對象

19? ? save(state, action) {

20? ? ? return { ...state, ...action.payload };

21? ? },

22? },

23

24 };

復(fù)制代碼

4,app.router(Function):注冊路由表,我們做路由跳轉(zhuǎn)的地方

復(fù)制代碼

1 import React from 'react';

2 import { routerRedux, Route ,Switch} from 'dva/router';

3 import { LocaleProvider } from 'antd';

4 import App from '../components/App/App';

5 import Flex from '../components/Header/index';

6 import Login from '../pages/Login/Login';

7 import Home from '../pages/Home/Home';

8 import zhCN from 'antd/lib/locale-provider/zh_CN';

9 const {ConnectedRouter} = routerRedux;

10

11 function RouterConfig({history}) {

12? return (

13? ? <ConnectedRouter history={history}>

14? ? ? <Switch>

15? ? ? ? <Route path="/login"? component={Login} />

16? ? ? ? <LocaleProvider locale={zhCN}>

17? ? ? ? <App>

18? ? ? ? ? <Flex>

19? ? ? ? ? ? <Switch>

20? ? ? ? ? ? <Route path="/"? exact component={Home} />

21? ? ? ? ? ? </Switch>

22? ? ? ? ? </Flex>

23? ? ? ? </App>

24? ? ? ? </LocaleProvider>

25? ? ? </Switch>

26? ? </ConnectedRouter>

27? );

28 }

29

30 export default RouterConfig;

復(fù)制代碼

5,app.start([HTMLElement], opts)

啟動我們自己的應(yīng)用

3.2,DvaJS的十個概念

1,Model

model 是 dva 中最重要的概念,Model 非 MVC 中的 M,而是領(lǐng)域模型,用于把數(shù)據(jù)相關(guān)的邏輯聚合到一起,幾乎所有的數(shù)據(jù),邏輯都在這邊進行處理分發(fā)

復(fù)制代碼

1 import Model from 'dva-model';

2 // import effect from 'dva-model/effect';

3 import queryString from 'query-string';

4 import pathToRegexp from 'path-to-regexp';

5 import {ManagementPage as namespace} from '../../utils/namespace';

6 import {

7? getPages,

8 } from '../../services/page';

9

10 export default Model({

11? namespace,

12? subscriptions: {

13? ? setup({dispatch, history}) {? // eslint-disable-line

14? ? ? history.listen(location => {

15? ? ? ? const {pathname, search} = location;

16? ? ? ? const query = queryString.parse(search);

17? ? ? ? const match = pathToRegexp(namespace + '/:action').exec(pathname);

18? ? ? ? if (match) {

19? ? ? ? ? ? dispatch({

20? ? ? ? ? ? ? type:'getPages',

21? ? ? ? ? ? payload:{

22? ? ? ? ? ? ? ? s:query.s || 10,

23? ? ? ? ? ? ? ? p:query.p || 1,

24? ? ? ? ? ? ? ? j_code:parseInt(query.j,10) || 1,

25? ? ? ? ? ? ? }

26? ? ? ? ? ? });

27? ? ? ? }

28

29? ? ? })

30? ? }

31? },

32? reducers: {

33? ? getPagesSuccess(state, action) {

34? ? ? const {list, total} = action.result;

35? ? ? return {...state, list, loading: false, total};

36? ? },

37? }

38 }, {

39? getPages,

40 })

復(fù)制代碼

2,namespace

model 的命名空間,同時也是他在全局 state 上的屬性,只能用字符串,我們發(fā)送在發(fā)送 action 到相應(yīng)的 reducer 時,就會需要用到 namespace

3,State(狀態(tài))

初始值,我們在 dva() 初始化的時候和在 modal 里面的 state 對其兩處進行定義,其中 modal 中的優(yōu)先級低于傳給 dva() 的 opts.initialState

復(fù)制代碼

1 // dva()初始化

2 const app = dva({

3? initialState: { count: 1 },

4 });

5

6 // modal()定義事件

7 app.model({

8? namespace: 'count',

9? state: 0,

10 });

復(fù)制代碼

Model中state的優(yōu)先級比初始化的低,但是基本上項目中的 state 都是在這里定義的

4,Subscription

Subscriptions 是一種從 源 獲取數(shù)據(jù)的方法,它來自于 elm。語義是訂閱,用于訂閱一個數(shù)據(jù)源,然后根據(jù)條件 dispatch 需要的 action。數(shù)據(jù)源可以是當(dāng)前的時間、服務(wù)器的 websocket 連接、keyboard 輸入、geolocation 變化、history 路由變化等等

復(fù)制代碼

1 subscriptions: { //觸發(fā)器。setup表示初始化即調(diào)用。

2? ? setup({dispatch, history}) {

3? ? ? history.listen(location => {//listen監(jiān)聽路由變化 調(diào)用不同的方法

4? ? ? ? if (location.pathname === '/login') {

5? ? ? ? ? //清除緩存

6? ? ? ? } else {

7? ? ? ? ? dispatch({

8? ? ? ? ? ? type: 'fetch'

9? ? ? ? ? });

10? ? ? ? }

11? ? ? });

12? ? },

13? },

復(fù)制代碼

5,Effects

用于處理異步操作和業(yè)務(wù)邏輯,不直接修改 state,簡單的來說,就是獲取從服務(wù)端獲取數(shù)據(jù),并且發(fā)起一個 action 交給 reducer 的地方。其中它用到了redux-saga里面有幾個常用的函數(shù)。

put? 用來發(fā)起一條action

call 以異步的方式調(diào)用函數(shù)

select 從state中獲取相關(guān)的數(shù)據(jù)

take 獲取發(fā)送的數(shù)據(jù)

復(fù)制代碼

1 effects: {

2? ? *login(action, saga){

3? ? ? const data = yield saga.call(effect(login, 'loginSuccess', authCache), action, saga);//call 用戶調(diào)用異步邏輯 支持Promise

4? ? ? if (data && data.token) {

5? ? ? ? yield saga.put(routerRedux.replace('/home'));//put 用于觸發(fā)action 什么是action下面會講到

6? ? ? }

7? ? },

8? ? *logout(action, saga){

9? ? ? const state = yield saga.select(state => state);//select 從state里獲取數(shù)據(jù)

10? ? },

11?

12? },

復(fù)制代碼

復(fù)制代碼

1 reducers: {

2? ? add1(state) {

3? ? ? const newCurrent = state.current + 1;

4? ? ? return { ...state,

5? ? ? ? record: newCurrent > state.record ? newCurrent : state.record,

6? ? ? ? current: newCurrent,

7? ? ? };

8? ? },

9? ? minus(state) {

10? ? ? return { ...state, current: state.current - 1};

11? ? },

12? },

13? effects: {

14? ? *add(action, { call, put }) {

15? ? ? yield put({ type: 'add1' });

16? ? ? yield call(delayDeal, 1000);

17? ? ? yield put({ type: 'minus' });

18? ? },

19? },

復(fù)制代碼

如果effect與reducers中的add方法重合了,這里會陷入一個死循環(huán),因為當(dāng)組件發(fā)送一個dispatch的時候,model會首先去找effect里面的方法,當(dāng)又找到add的時候,就又會去請求effect里面的方法。

這里的 delayDeal,是我這邊寫的一個延時的函數(shù),我們在 utils 里面編寫一個 utils.js

復(fù)制代碼

1 /**

2? *超時函數(shù)處理

3? * @param timeout? :timeout超時的時間參數(shù)

4? * @returns {*} :返回樣式值

5? */

6 export function delayDeal(timeout) {

7? return new Promise((resolve) => {

8? ? setTimeout(resolve, timeout);

9? });

10 }

復(fù)制代碼

接著我們在 models/example.js 導(dǎo)入這個 utils.js

1 import { delayDeal} from '../utils/utils';

6,Reducer

以key/value 格式定義 reducer,用于處理同步操作,唯一可以修改 state 的地方。由 action 觸發(fā)。其實一個純函數(shù)。

1? reducers: {

2? ? loginSuccess(state, action){

3? ? ? return {...state, auth: action.result, loading: false};

4? ? },

5? }

7,Router

Router 表示路由配置信息,項目中的 router.js

8,RouteComponent

RouteComponent 表示 Router 里匹配路徑的 Component,通常會綁定 model 的數(shù)據(jù)

9,Action:表示操作事件,可以是同步,也可以是異步

action 的格式如下,它需要有一個 type ,表示這個 action 要觸發(fā)什么操作;payload則表示這個 action 將要傳遞的數(shù)據(jù)

復(fù)制代碼

1 {

2? ? ? type: namespace + '/login',

3? ? ? payload: {

4? ? ? ? ? userName: payload.userName,

5? ? ? ? ? password: payload.password

6? ? ? ? }

7? }

復(fù)制代碼

構(gòu)建一個Action 創(chuàng)建函數(shù),如下:

復(fù)制代碼

1 function goLogin(payload) {

2 let loginInfo = {

3? ? ? ? ? ? type: namespace + '/login',

4? ? ? ? ? ? payload: {

5? ? ? ? ? ? ? userName: payload.userName,

6? ? ? ? ? ? ? password: payload.password

7? ? ? ? ? ? }

8? ? ? ? ? }

9? return loginInfo

10 }

11

12 //我們直接dispatch(goLogin()),就發(fā)送了一個action。

13 dispatch(goLogin())

復(fù)制代碼

10,dispatch

type dispatch = (a: Action) => Action

dispatching function 是一個用于觸發(fā) action 的函數(shù),action 是改變 State 的唯一途徑,但是它只描述了一個行為,而 dipatch 可以看作是觸發(fā)這個行為的方式,而 Reducer 則是描述如何改變數(shù)據(jù)的。

在 dva 中,connect Model 的組件通過 props 可以訪問到 dispatch,可以調(diào)用 Model 中的 Reducer 或者 Effects,常見的形式如:

1 dispatch({

2? ? type: namespace + '/login', // 如果在 model 外調(diào)用,需要添加 namespace,如果在model內(nèi)調(diào)用 無需添加 namespace

3? payload: {}, // 需要傳遞的信息

4 });

reducers 處理數(shù)據(jù)

effects? 接收數(shù)據(jù)

subscriptions 監(jiān)聽數(shù)據(jù)

3.3,使用antd

先安裝 antd 和 babel-plugin-import

1 npm install antd babel-plugin-import --save

2 # 或

3 yarn add antd babel-plugin-import

babel-plugin-import 也可以通過 -D 參數(shù)安裝到 devDependencies 中,它用于實現(xiàn)按需加載。然后在 .webpackrc 中添加如下配置:

復(fù)制代碼

1 {

2? "extraBabelPlugins": [

3? ? ["import", {

4? ? ? "libraryName": "antd",

5? ? ? "libraryDirectory": "es",

6? ? ? "style": true

7? ? }]

8? ]

9 }

復(fù)制代碼

現(xiàn)在就可以按需引入 antd 的組件了,如 import { Button } from 'antd',Button 組件的樣式文件也會自動幫你引入。

3.4,配置.webpackrc

1,entry是入口文件配置

單頁類型:

1 entry: './src/entries/index.js',

多頁類型:

1 "entry": "src/entries/*.js"

2,extraBabelPlugins 定義額外的 babel plugin 列表,格式為數(shù)組。

3,env針對特定的環(huán)境進行配置。dev 的環(huán)境變量是?development,build 的環(huán)境變量是?production。

復(fù)制代碼

1 "extraBabelPlugins": ["transform-runtime"],

2 "env": {

3? development: {

4? ? ? extraBabelPlugins: ['dva-hmr'],

5? ? },

6? ? production: {

7? ? ? define: {

8? ? ? ? __CDN__: process.env.CDN ? '//cdn.dva.com/' : '/' }

9? ? }

10 }

復(fù)制代碼

開發(fā)環(huán)境下的 extraBabelPlugins 是?["transform-runtime", "dva-hmr"],而生產(chǎn)環(huán)境下是?["transform-runtime"]

4,配置 webpack 的?externals?屬性

1 // 配置 @antv/data-set和 rollbar 不打入代碼

2 "externals": {

3? ? '@antv/data-set': 'DataSet',

4? ? rollbar: 'rollbar',

5 }

5,配置 webpack-dev-server 的 proxy 屬性。 如果要代理請求到其他服務(wù)器,可以這樣配:

復(fù)制代碼

1? proxy: {

2? ? "/api": {

3? ? ? // "target": "http://127.0.0.1/",

4? ? ? // "target": "http://127.0.0.1:9090/",

5? ? ? "target": "http://localhost:8080/",

6? ? ? "changeOrigin": true,

7? ? ? "pathRewrite": { "^/api" : "" }

8? ? }

9? },

復(fù)制代碼

6,disableDynamicImport

禁用 import() 按需加載,全部打包在一個文件里,通過 babel-plugin-dynamic-import-node-sync 實現(xiàn)。

7,publicPath

配置 webpack 的 output.publicPath 屬性。

8,extraBabelIncludes

定義額外需要做 babel 轉(zhuǎn)換的文件匹配列表,格式為數(shù)組

9,outputPath

配置 webpack 的 output.path 屬性。

打包輸出的文件

1 config["outputPath"] = path.join(process.cwd(), './build/')

10,根據(jù)需求完整配置如下:

文件名稱是:.webpackrc.js,可根據(jù)實際情況添加如下代碼:

復(fù)制代碼

1 const path = require('path');

2

3 const config = {

4? entry: './src/entries/index.js',

5? extraBabelPlugins: [['import', { libraryName: 'antd', libraryDirectory: 'es', style: true }]],

6? env: {

7? ? development: {

8? ? ? extraBabelPlugins: ['dva-hmr'],

9? ? },

10? ? production: {

11? ? ? define: {

12? ? ? ? __CDN__: process.env.CDN ? '//cdn.dva.com/' : '/' }

13? ? }

14? },

15? externals: {

16? ? '@antv/data-set': 'DataSet',

17? ? rollbar: 'rollbar',

18? },

19? lessLoaderOptions: {

20? ? javascriptEnabled: true,

21? },

22? proxy: {

23? ? "/api": {

24? ? ? // "target": "http://127.0.0.1/",

25? ? ? // "target": "http://127.0.0.1:9090/",

26? ? ? "target": "http://localhost:8080/",

27? ? ? "changeOrigin": true,

28? ? }

29? },

30? es5ImcompatibleVersions:true,

31? disableDynamicImport: true,

32? publicPath: '/',

33? hash: false,

34? extraBabelIncludes:[

35? ? "node_modules"

36? ]

37 };

38 if (module.exports.env !== 'development') {

39? config["outputPath"] = path.join(process.cwd(), './build/')

40 }

41 export default config

復(fù)制代碼

更多 .webpackrc 的配置請參考 roadhog 配置。

3.5,使用antd-mobile

先安裝 antd-mobile 和 babel-plugin-import

1 npm install antd-mobile babel-plugin-import --save # 或

2 yarn add antd-mobile babel-plugin-import

babel-plugin-import 也可以通過 -D 參數(shù)安裝到 devDependencies 中,它用于實現(xiàn)按需加載。然后在 .webpackrc 中添加如下配置:

1 {

2? "plugins": [

3? ? ["import", { libraryName: "antd-mobile", style: "css" }] // `style: true` 會加載 less 文件

4? ]

5 }

現(xiàn)在就可以按需引入antd-mobile 的組件了,如 import { DatePicker} from 'antd-mobile',DatePicker 組件的樣式文件也會自動幫你引入。

四,整體架構(gòu)

我們根據(jù) url 訪問相關(guān)的 Route-Component,在組件中我們通過 dispatch 發(fā)送 action 到 model 里面的 effect 或者直接 Reducer

當(dāng)我們將action發(fā)送給Effect,基本上是取服務(wù)器上面請求數(shù)據(jù)的,服務(wù)器返回數(shù)據(jù)之后,effect 會發(fā)送相應(yīng)的 action 給 reducer,由唯一能改變 state 的 reducer 改變 state ,然后通過connect重新渲染組件。

當(dāng)我們將action發(fā)送給reducer,那直接由 reducer 改變 state,然后通過 connect 重新渲染組件。如下圖所示:

數(shù)據(jù)流向

數(shù)據(jù)的改變發(fā)生通常是通過用戶交互行為或者瀏覽器行為(如路由跳轉(zhuǎn)等)觸發(fā)的,當(dāng)此類行為會改變數(shù)據(jù)的時候可以通過 dispatch 發(fā)起一個 action,如果是同步行為會直接通過 Reducers 改變 State ,如果是異步行為(副作用)會先觸發(fā) Effects 然后流向 Reducers 最終改變 State

重置models里的數(shù)據(jù):

1 dispatch({type:namespace+'/set',payload:{mdata:[]}});

? set是內(nèi)置的方法

Dva官方文檔? ? ? ? ? ? ? nginx代理部署Vue與React項目

五,問題記錄

5.1,路由相關(guān)的問題

1,使用match后的路由跳轉(zhuǎn)問題,版本routerV4

match是一個匹配路徑參數(shù)的對象,它有一個屬性params,里面的內(nèi)容就是路徑參數(shù),除常用的params屬性外,它還有url、path、isExact屬性。

問題描述:不能跳轉(zhuǎn)新頁面或匹配跳轉(zhuǎn)后,刷新時url所傳的值會被重置掉

不能跳轉(zhuǎn)的情況

復(fù)制代碼

1 const {ConnectedRouter} = routerRedux;

2

3 function RouterConfig({history}) {

4 const tests =({match}) =>(

5? ? <div>

6? ? ? <Route exact path={`${match.url}/:tab`} component={Test}/>

7? ? ? <Route exact path={match.url} component={Test}/>

8? ? </div>

9

10? );

11? return (

12? ? <ConnectedRouter history={history}>

13? ? ? <Switch>

14? ? ? ? <Route path="/login" component={Login}/>

15? ? ? ? <LocaleProvider locale={zhCN}>

16? ? ? ? ? <App>

17? ? ? ? ? ? <Flex>

18? ? ? ? ? ? ? <Switch>

19? ? ? ? ? ? ? ? <Route path="/test" component={tests }/>

20? ? ? ? ? ? ? ? <Route exact path="/test/bindTest" component={BindTest}/>

21? ? ? ? ? ?

22? ? ? ? ? ? ? </Switch>

23? ? ? ? ? ? </Flex>

24? ? ? ? ? </App>

25? ? ? ? </LocaleProvider>

26? ? ? </Switch>

27? ? </ConnectedRouter>

28? );

29 }

復(fù)制代碼

路由如上寫法,使用下面方式不能跳轉(zhuǎn),但是地址欄路徑變了

復(fù)制代碼

1 import { routerRedux} from 'dva/router';

2 ...

3?

4 this.props.dispatch(routerRedux.push({

5? ? ? pathname: '/test/bindTest',

6? ? ? search:queryString.stringify({

7? ? ? ? // ...query,

8? ? ? ? Code: code,

9? ? ? ? Name: name

10? ? ? })

11? ? }));

12

13 ...

復(fù)制代碼

能跳轉(zhuǎn),但是刷新所傳的參數(shù)被重置

復(fù)制代碼

1 const {ConnectedRouter} = routerRedux;

2

3 function RouterConfig({history}) {

4 const tests =({match}) =>(

5? ? <div>

6? ? ? <Route exact path={`${match.url}/bindTest`} component={BindTest}/>

7? ? ? <Route exact path={`${match.url}/:tab`} component={Test}/>

8? ? ? <Route exact path={match.url} component={Test}/>

9? ? </div>

10

11? );

12? return (

13? ? <ConnectedRouter history={history}>

14? ? ? <Switch>

15? ? ? ? <Route path="/login" component={Login}/>

16? ? ? ? <LocaleProvider locale={zhCN}>

17? ? ? ? ? <App>

18? ? ? ? ? ? <Flex>

19? ? ? ? ? ? ? <Switch>

20? ? ? ? ? ? ? ? <Route path="/test" component={tests }/>

21? ? ? ? ? ? ? </Switch>

22? ? ? ? ? ? </Flex>

23? ? ? ? ? </App>

24? ? ? ? </LocaleProvider>

25? ? ? </Switch>

26? ? </ConnectedRouter>

27? );

28 }

復(fù)制代碼

路由如上寫法,使用下面方式可以跳轉(zhuǎn),但是刷新時所傳的參數(shù)會被test里所傳的參數(shù)重置

復(fù)制代碼

1 ...

2

3 this.props.dispatch(routerRedux.push({

4? ? ? ? pathname: '/test/bindTest',

5? ? ? ? search:queryString.stringify({

6? ? ? ? ? // ...query,

7? ? ? ? ? Code: code,

8? ? ? ? ? Name: name

9? ? ? ? })

10 }));

11

12 ...

復(fù)制代碼

解決辦法如下:地址多加一級,跳出以前的界面

路由配置

復(fù)制代碼

1 const {ConnectedRouter} = routerRedux;

2

3 function RouterConfig({history}) {

4 const tests =({match}) =>(

5? ? <div>

6? ? ? <Route exact path={`${match.url}/bind/test`} component={BindTest}/>

7? ? ? <Route exact path={`${match.url}/:tab`} component={Test}/>

8? ? ? <Route exact path={match.url} component={Test}/>

9? ? </div>

10

11? );

12? return (

13? ? <ConnectedRouter history={history}>

14? ? ? ? ? ? ? <Switch>

15? ? ? ? ? ? ? ? <Route path="/test" component={tests }/>

16? ? ? ? ? ? ? </Switch>

17? ? </ConnectedRouter>

18? );

19 }

復(fù)制代碼

調(diào)用

復(fù)制代碼

1 ...

2?

3 this.props.dispatch(routerRedux.push({

4? ? ? pathname: '/test/bind/test1',

5? ? ? search:queryString.stringify({

6? ? ? ? // ...query,

7? ? ? ? Code: code,

8? ? ? ? Name: name

9? ? ? })

10? ? }));

11

12 ...

東莞網(wǎng)站建設(shè)www.zg886.cn

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容