02使用路由、redux以及本地mock数据

react-router
redux
redux例子
01中使用webpack创建了react项目,该部分使用react-router进行路由管理,使用redux进行state管理。

使用react-router

1.安装npm install react-router-dom --save-dev
2.在src中创建router文件夹,并在其中创建index.js文件

import React from 'react';
import Home from '../pages/home/index';
import Column from '../pages/column/index';
import Analysis from '../pages/analysis/index'
import { Router, Route, Switch } from 'react-router-dom';
const history = createHashHistory(); 
import { createHashHistory } from "history";


class RouterConfig extends React.Component{
    render(){
        return(
            <Router history={history}>
                <Switch>
                    <Route path='/' exact component={Home}></Route>
                    <Route path="/home" component={Home}></Route>
                    <Home>
                        <Route exact path="/column" component={Column}></Route>
                        <Route exact path="/analysis" component={Analysis}></Route>
                    </Home>
                </Switch>
            </Router>
        )
    }
}
export default RouterConfig;

这里需要说明几个问题:

  • switch和exact都是避免重复渲染的,这两种方法都可以唯一准确的匹配url
  • 嵌套路由,将作为父页面包裹住子页面即可

3.最后将入口文件修改为

ReactDOM.render(
    <div>
        <RouterConfig />
    </div>,
    document.getElementById('root')
);

使用mock模拟后台数据

1.安装npm install mocker-api --save-dev
2.在src文件夹中创建mock文件夹,新建index.js文件以及需要引入的mock数据文件,这里的例子是menuInfo.js
3.在mock文件夹index.js中配置如下:

//引入的数据文件menuInfo.js
const menuInfo = require("./menuInfo")

const proxy = {
    'GET /api/menu': menuInfo
}

module.exports = proxy

4.在webpack.config.js中devServer里添加配置

devServer: {
    before (app) {
         apiMocker(app, path.resolve('./src/mock/index.js'))
     },
     ...
}

到此为止,mock就配置好了,接下来就是使用axios发送请求

使用axios发送异步请求

1.安装npm install axios --save-dev
2.在需要使用的地方引入import axios from 'axios';即可,这部分代码后面说明

使用redux

1.安装

npm install redux --save -dev //安装redux
npm install --save react-rudex //搭配react使用
npm install redux-thunk --save-dev //使用中间件 redux-thunk 

2.在src中创建store文件夹,在其中新建index.js,action.js,reducers.js,state.js

//state.js
//声明状态的默认值
export default {
    homeTitle: "主页",
    menuList: []
}
//actions.js
//所有的action定义
import axios from 'axios';

 export function setHomeTitle (data) {
    return {
        type: 'SET_HOME_TITLE', //action的type值,必须
        data: data //action携带的数据,非必须
    }
 }
 export function setMenuList (list) {
     return {
         type: 'SET_MENU_LIST',
         data: list
     }
 }
 //异步action,中间件就是用来处理异步action的
 export function getMenuList () {
     return async dispatch => {
        const res = await axios.get('/api/menu');
        console.log(res);
        if(res.status == 200) {
            console.log(res.data.data.menuList);
            dispatch(setMenuList(res.data.data.menuList));
        }
     }
 }
//reducers.js
//根据action的type来返回重新计算state中的值,reducers中的函数是自动去调用的

//工具函数,用于组织多个reducer,并返回reducer集合
import { combineReducers } from 'redux';
//导入默认值
import defaultState from './state.js'

//一个reducer就是一个函数
function homeTitle (state = defaultState.homeTitle, action) {
    switch (action.type) {
        case 'SET_HOME_TITLE':
            return action.data;
        default:
            return state;
    }
}

function menuList (state = defaultState.menuList, action) {
    switch (action.type) {
        case 'SET_MENU_LIST':
            return action.data;
        default:
            return state;
    }
}

//导出所有reducer,combineReducers接收一个拆分后 reducer 函数组成的对象,返回一个新的 Reducer 函数
export default combineReducers({
    homeTitle,
    menuList
})
//index.js 
//创建store对象
//applyMiddleware:redux通过该函数来使用中间件
//createStore:用于创建store实例
import { applyMiddleware, createStore } from 'redux';
//中间件
import thunk from 'redux-thunk';

import reducers from './reducers.js';

let store = createStore(
    reducers,
    applyMiddleware(thunk)
)

export default store;

3.修改入口文件

//引入provider,是react-redux两个核心工具之一(第二个connect,在组件中使用),将store传递到每个项目组件中去
import { Provider } from 'react-redux';
//引入创建好的store实例
import store from './store/index';

ReactDOM.render(
    <div>
        {/* 将store作为prop传入,即可使应用中的所有组件使用store */}
        <Provider store={store}>
            <RouterConfig />
        </Provider>
    </div>,
    document.getElementById('root')
);

4.组件中使用
Home

import { connect } from 'react-redux';
//引入action
import { setHomeTitle, getMenuList } from '@/store/actions.js'

class Home extends Component {
    constructor(props) {
        super(props);
        //定义state的初始值和绑定函数
        this.state = {
            collapsed: false,
           // menuList: []
        };
        this.toggleCollapsed = this.toggleCollapsed.bind(this);
    }
componentDidMount () {
    let { setHomeTitle, getMenuList } = this.props;
    setHomeTitle('hometitle');
    //setMenuList();
    getMenuList();
    
}
toggleCollapsed (){
        this.setState({
            collapsed: !this.state.collapsed,
        });
    };
render() {
        //从props中解构出store
        let { homeTitle, menuList } = this.props;
        const menuItem = menuList.map((item) => {
            //console.log(item.id)
            return (
                <p key={item.id}>{item.description}</p>
            )
           
        })
        console.log(homeTitle)
        // console.log(menuList)
        return (
            <div style={{ width: 256 }}>
                <h1>{homeTitle}</h1>
                <div>{menuItem}</div>
            </div>
        )
  }
}

const mapStateToProps = (state) => {
    return {
        homeTitle: state.homeTitle,
        menuList: state.menuList
    }
}
const mapDispatchToProps = (dispatch, ownProps) => {
    return {
        setHomeTitle (data) {
            dispatch(setHomeTitle(data))
        },
        getMenuList () {
            dispatch(getMenuList())
        }
    }
}
//连接store和组件
export default connect(mapStateToProps, mapDispatchToProps)(Home);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值