手动使用typescript+webpack搭建react开发环境(二路由的使用)

一、简单的使用路由

  • 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组件的locationstate里面(常见在列表页面和详情页面传递数据)

二、使用路由的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中使用connectRouterhistoryredux连接起来

    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)
    

猜你喜欢

转载自blog.csdn.net/kuangshp128/article/details/108895505