一、简单的使用路由
-
1、需要安装依赖包
npm install react-router-dom
-
2、简单创建2个组件
-
3、在
src/index.tsx
文件中配置路由的使用import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom' import { ConfigProvider } from 'antd' import zh_CN from 'antd/lib/locale-provider/zh_CN'; import store from './store'; import Counter from '@/components/Counter'; import Home from '@/components/Home'; // 全局样式 import './assets/style/common.less'; ReactDOM.render( <Provider store={store}> <ConfigProvider locale={zh_CN}> <Router> {/* 注意使用路由的时候都要包一层 */} <React.Fragment> <ul> <li> <Link to="/">首页</Link> </li> <li> <Link to="/counter">计数页面</Link> </li> </ul> <Switch> <Route path='/' exact component={Home} /> <Route path='/counter' component={Counter} /> </Switch> </React.Fragment> </Router> </ConfigProvider> </Provider>, document.getElementById('root') )
-
4、路由正常使用
-
5、使用路由后,在组件中打印出
this.props
会多出几个字段history // 提供一些操作路由的方法 location // 当前路由的信息 match // 匹配的路由信息
-
6、传统的方式如果在组件中要进行页面跳转
import React, { PropsWithChildren } from 'react'; import { connect } from 'react-redux'; import { Button } from 'antd'; import action from '@/store/actions/counter'; import { CombinedState } from '@/typings'; // 新增的代码 import { RouteComponentProps } from 'react-router-dom'; import { StaticContext } from 'react-router'; interface Params { name: string } interface LocationState { } // 新增路由的参数约束 type Props = PropsWithChildren<RouteComponentProps<Params, StaticContext, LocationState> & ReturnType<typeof mapStateToProps> & typeof action>; // 随便定义一个,可以不写 type State = { [propsName: string]: any } class Counter extends React.Component<Props, State> { render() { console.log(this.props); return ( <> ... <Button type="primary" onClick={() => this.props.history.push({ pathname: "/", state: { name: '哈哈' } })}>到首页</Button> ... </> ) } } const mapStateToProps = (state: CombinedState) => (state.counter) export default connect( mapStateToProps, action, )(Counter)
-
7、
state
会传递到Home
组件的location
的state
里面(常见在列表页面和详情页面传递数据)
二、使用路由的redux
中间件,将路由与redux
配置
-
1、安装依赖包
npm install connected-react-router
-
2、在项目的
src
目录下创建一个history.ts
的文件import { createBrowserHistory } from 'history'; export default createBrowserHistory();
-
3、在
typings/state.ts
文件中新增路由的类型import { CounterState } from '.'; import { RouterState } from 'connected-react-router'; // 各个组件的reducer的状态类型(每次新增reducer的就要在这里添加) export interface CombinedState { counter: CounterState, router: RouterState, }
-
4、在
/src/store/reducers/index.ts
中使用connectRouter
将history
与redux
连接起来import { ReducersMapObject, Reducer, combineReducers, AnyAction, Dispatch } from 'redux'; // 新增连接 import { connectRouter } from 'connected-react-router'; import history from '@/history'; import counter from './counter'; import { CombinedState } from '@/typings'; const reducers: ReducersMapObject<CombinedState, AnyAction> = { // 各个组件的reducer counter, // 新增路由连接 router: connectRouter(history) }; const rootReducers: Reducer<CombinedState, any> = combineReducers(reducers); export type StoreDispatch = Dispatch; export type StoreGetState = () => CombinedState; export default rootReducers;
-
5、在
src/store/index.ts
中配置连接的中间件import { createStore, applyMiddleware } from 'redux'; import logger from 'redux-logger'; import promise from 'redux-promise'; import thunk from 'redux-thunk'; import { composeWithDevTools } from 'redux-devtools-extension' import { routerMiddleware } from 'connected-react-router'; import history from '@/history'; import rootReducer from './reducers'; const enhancers = process.env.NODE_ENV === "development" ? composeWithDevTools( applyMiddleware(routerMiddleware(history), promise, thunk, logger) ) : applyMiddleware(routerMiddleware(history), promise, thunk); const store = createStore(rootReducer, enhancers); export default store;
-
6、在
src/index.tsx
中使用history.ts
文件... import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import { BrowserRouter as Router, Route, Switch, Link, Redirect } from 'react-router-dom' import { ConfigProvider } from 'antd' import zh_CN from 'antd/lib/locale-provider/zh_CN'; import store from './store'; import Counter from '@/components/Counter'; import Home from '@/components/Home'; import { ConnectedRouter } from 'connected-react-router'; import history from './history'; // 全局样式 import './assets/style/common.less'; ReactDOM.render( <Provider store={store}> <ConnectedRouter history={history}> <ConfigProvider locale={zh_CN}> {/*注意这个地方,如果使用了connected-react-router就不需要使用Router*/} <ul> <li> <Link to="/">首页</Link> </li> <li> <Link to="/counter">计数页面</Link> </li> </ul> <Switch> <Route path='/' exact component={Home} /> <Route path='/counter' component={Counter} /> <Redirect to="/" /> </Switch> </ConfigProvider> </ConnectedRouter> </Provider>, document.getElementById('root') )
三、使用redux
对路由的操作
-
1、在
/src/store/actions/counter.ts
中创建一个路由跳转的方法import * as types from './../action-types'; import { CounterPayload } from '@/typings'; import { activityList } from '@/api'; import { StoreDispatch, StoreGetState } from '../reducers'; import { CallHistoryMethodAction, push } from 'connected-react-router'; import { LocationDescriptorObject } from 'history'; export default { ... // 返回首页 goHome(path: LocationDescriptorObject<any>): CallHistoryMethodAction { console.log('path', path); return push(path) } }
-
2、在组件中使用
import React, { PropsWithChildren } from 'react'; import { connect } from 'react-redux'; import { Button } from 'antd'; import action from '@/store/actions/counter'; import { CombinedState } from '@/typings'; import { RouteComponentProps } from 'react-router-dom'; import { StaticContext } from 'react-router'; interface Params { name: string } interface LocationState { } type Props = PropsWithChildren<RouteComponentProps<Params, StaticContext, LocationState> & ReturnType<typeof mapStateToProps> & typeof action>; // 随便定义一个,可以不写 type State = { [propsName: string]: any } class Counter extends React.Component<Props, State> { render() { console.log(this.props); return ( <> {/*直接使用this.props.goHome到actions中*/} <Button type="primary" onClick={() => this.props.goHome({ pathname: "/", state: { name: '哈哈' } })}>到首页</Button> </> ) } } const mapStateToProps = (state: CombinedState) => (state.counter) export default connect( mapStateToProps, action, )(Counter)