1. 前言
首先赘述一遍各个框架的官方口号
React
用于构建用户界面的
JavaScript
库
Redux
Redux
是JavaScript
状态容器,提供可预测化的状态管理
React-Router
通过管理
URL
,实现组件的切换和状态的变化
React-Thunk和React-Saga
Redux store
仅支持同步数据流。使用thunk
等中间件可以帮助在Redux
应用中实现异步性
React
通过声明式渲染和组件化很好的胜任了UI
层面的工作,但是没有路由功能(管理页面之间的切换)和状态容器(管理全局数据),action
中也不能执行异步操作,所以就有了react-router
和redux
和thunk
。
2. 全家桶整合实例代码(基于Creat-React-App
脚手架)
入口文件src/index.jsx
(整合redux
和thunk
,其中ConnectedRouter
是为了把redux
中整合的router
数据和react
组件的router
数据联系起来,不然在action
里是没办法正确跳转的)
import React from "react"
import ReactDom from "react-dom"
import MyApp from "./app"
import {createStore,applyMiddleware} from "redux"
import rootReducers from "./reducer/index"
import {Provider} from "react-redux"
import reduxThunk from "redux-thunk"
import { ConnectedRouter} from 'connected-react-router'
import history from "@/actions/history";
const store = createStore(rootReducers,{},applyMiddleware(logger,reduxThunk))
ReactDom.render(
,
document.getElementById("app"))
redux
入口文件/src/redux/index.js
(整合自己全部的reducer
,同时整合history
实现action
里路由跳转)
import login from './login' //这里可以写自己的reducer
import { combineReducers } from 'redux'
import { connectRouter } from 'connected-react-router'
import history from "@/actions/history";
//history模块是为了能在action里面进行路由跳转
const reducers = combineReducers ({
router: connectRouter(history),
login,
})
export default reducers
actions
文件夹下的主要文件
/src/actions/hisotry.js
import {createBrowserHistory} from 'history';
const history = createBrowserHistory()
export default history;
/src/actions/login.js
import { push } from 'react-router-redux'
export const login = ({payload}) => (dispatch) => {
//模拟登陆,异步请求后执行跳转跳转
setTimeout(() => {
dispatch(push('/home'))
}, 1000)
}
最后就是app.jsx
文件(使用路由)
import React, {Fragment} from "react"
import {BrowserRouter as Router, Route, Link, NavLink, Switch,} from 'react-router-dom';
const mapStateToProps = (state) => ({
login: state.login,
})
const mapDispatchToProps = (dispatch) => ({
loginApi: (payload) => {
login(payload)(dispatch)
}
})
@withRouter
@connect(mapStateToProps, mapDispatchToProps)
export default class MyApp extends React.Component {
render() {
return (
//里面可以写自己的页面
);
}
}
看到这里是不是觉得头都大了,没错,为了把react
,router
,redux
三者完美的联系起来,需要配置的东西太多了,严重影响开发效率。所以此时Dva
和Umi
等React
框架就应运而生了。
3. Dva
首先老惯例还是看一下官网介绍
dva
首先是一个基于 redux 和 redux-saga 的数据流方案,然后为了简化开发体验,dva
还额外内置了 react-router 和 fetch,所以也可以理解为一个轻量级的应用框架。
光说不练假把式,我们快速创建一个dva
脚手架项目看看结构
npm install dva-cli -g
dva new dva-quickstart
cd dva-quickstart
npm start
目录结构
Dva
帮我们整合了很多东西,在index.js
里,通过几个API
就整合了router
和redux
//index.js
import dva from 'dva';
import './index.css';
// 1. Initialize
const app = dva();
// 2. Plugins
// app.use({});
// 3. Model
// app.model(require('./models/example').default);
// 4. Router
app.router(require('./router').default);
// 5. Start
app.start('#root');
页面连接redux
import React from 'react';
import { connect } from 'dva';
import styles from './IndexPage.css';
function IndexPage() {
return (
);
}
IndexPage.propTypes = {
};
export default connect()(IndexPage);
而且还提出了极具规范性的model
import {routerRedux} from 'dva/router'
export default {
namespace: 'example',
state: {},
subscriptions: {
setup({ dispatch, history }) { // eslint-disable-line
},
},
effects: {
*fetch({ payload }, { call, put }) { // eslint-disable-line
yield put({ type: 'save' });
yield.put(routerRedux.push('/'))
},
},
reducers: {
save(state, action) {
return { ...state, ...action.payload };
},
},
};
model
其实就是把所有跟redux
相关的一个reducer
整合在一个model
文件里,通过namespace
区分model
,通过state
存储数据,通过subsciprtions
实现hisotry
等监听,通过effect
发起异步操作,通过reducer
执行同步操作,简直完美!
看来Dva
已经帮我们规划好了一切,我们只要按着官网的API
文档,一部一部搭建自己的应用就好了。
但是牛逼的前人们不安于现状,Umi
横空出世
4. Umi 是什么?
老惯例
Umi
,中文可发音为乌米,是可扩展的企业级前端应用框架。Umi
以路由为基础的,同时支持配置式路由和约定式路由,保证路由的功能完备,并以此进行功能扩展。然后配以生命周期完善的插件体系,覆盖从源码到构建产物的每个生命周期,支持各种功能扩展和业务需求。
简单来说,
Umi
就是一个支持约定式路由和配置式路由的大杂烩,他整合了所有React生态的东西,Antd
、Dva
等等,把他们都当成了Umi
的插件,我们想使用的时候,直接通过配置就能使用
再一次口说无凭,我们快速创建一个Umi
脚手架项目看看结构
umi
官网推荐用yarn
代替npm
npm i yarn tyarn -g
mkdir myapp && cd myapp
yarn create @umijs/umi-app
yarn install
yarn start
目录结构
可以看到Umi实际上就只有
src
下的一个pages
文件夹(.Umi文件不用管,是项目启动之后动态构建的),内置了Dva(@umijs/plugin-dva)
,antd(@umijs/plugin-antd)
等功能。我们只需要写页面组件就好了,简直无敌
写在最后
当然了,Dva
和Umi
的功能虽然强大,但是为了很好的使用他们,我们必须花更多的时间去看官网文档,重头了解他们要如何使用,如何配置。而基于Webpack
构建的creat-react-app
让我们高的自由度,实现任何功能,对习惯了webpack
的人来说有种回家的感觉。