简述React全家桶,Dva,Umi的理解

·  阅读 3161
简述React全家桶,Dva,Umi的理解

1. 前言

首先赘述一遍各个框架的官方口号

  • React

用于构建用户界面的 JavaScript

  • Redux

ReduxJavaScript状态容器,提供可预测化的状态管理

  • React-Router

通过管理 URL,实现组件的切换和状态的变化

  • React-Thunk和React-Saga

Redux store 仅支持同步数据流。使用 thunk 等中间件可以帮助在 Redux 应用中实现异步性

React通过声明式渲染和组件化很好的胜任了UI层面的工作,但是没有路由功能(管理页面之间的切换)和状态容器(管理全局数据),action中也不能执行异步操作,所以就有了react-routerreduxthunk


2. 全家桶整合实例代码(基于Creat-React-App脚手架)

入口文件src/index.jsx (整合reduxthunk,其中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(
	<Provider store={store}>
		<ConnectedRouter history={history}>
			<MyApp/>
		</ConnectedRouter>
	</Provider>,
	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 (
			<Fragment>
				<Router>
				    <Switch>
                                        //里面可以写自己的页面
				    </Switch>
				</Router>
			</Fragment>
		);
	}
}
复制代码

看到这里是不是觉得头都大了,没错,为了把reactrouterredux三者完美的联系起来,需要配置的东西太多了,严重影响开发效率。所以此时DvaUmiReact框架就应运而生了。


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.png Dva帮我们整合了很多东西,在index.js里,通过几个API就整合了routerredux

//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 (
    <div className={styles.normal}>
    </div>
  );
}

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.png 简单来说,Umi就是一个支持约定式路由和配置式路由的大杂烩,他整合了所有React生态的东西,AntdDva等等,把他们都当成了Umi的插件,我们想使用的时候,直接通过配置就能使用

再一次口说无凭,我们快速创建一个Umi脚手架项目看看结构

umi官网推荐用yarn代替npm

npm i yarn tyarn -g
mkdir myapp && cd myapp
yarn create @umijs/umi-app
yarn install
yarn start
复制代码

目录结构 umi1.png 可以看到Umi实际上就只有src下的一个pages文件夹(.Umi文件不用管,是项目启动之后动态构建的),内置了Dva(@umijs/plugin-dva)antd(@umijs/plugin-antd)等功能。我们只需要写页面组件就好了,简直无敌

写在最后

当然了,DvaUmi的功能虽然强大,但是为了很好的使用他们,我们必须花更多的时间去看官网文档,重头了解他们要如何使用,如何配置。而基于Webpack构建的creat-react-app让我们有更高的自由度,实现任何功能,对习惯了webpack的人来说有种回家的感觉。

分类:
前端
标签:
分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改