一篇文章读懂 React redux 前端开发_第1页
一篇文章读懂 React redux 前端开发_第2页
一篇文章读懂 React redux 前端开发_第3页
一篇文章读懂 React redux 前端开发_第4页
一篇文章读懂 React redux 前端开发_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

DvaJS:Reactandreduxbased,lightweightandelm-styleframework.

/

实例项目源码:/AK-47-D/re...

快速上手

#安装dva-cli

通过npm安装dva-cli并确保版本是或以上。

$dva-cli-g

$dva-v

dva-cliversion(9.9.1

#创建新应用

安装完dva-cli之后,就可以在命令行里访问到村“命令(不能访问?)。现在,

你可以通过dvanew创建新应用。

于dvaMWdva-quickstaH

这会创建Aa-quickstart目录,包含项目初始化目录和文件,并提供开发服务器、

构建脚本、数据mock服务、代理服务器等功能。

然后我们cd进入dv汝rt目录,并启动开发服务器:

$cddva-quickstartinpmstart

几秒钟后,你会看到以下输出:

Compileds(xccessF川侬

Theappis八八ingat:

http://【ocalhost:3000/

Notethatthedevelopi^ei^tbuildisMtoptimized.Tocreateaproductionbuild,useupm八

build.

在浏览器里打开http://localhost:8000,你会看到dva的欢迎界面。

#使用antd

通过npm安装ai^td和babel-plugin-import。babel-plugin-import是用来按需加载

antd的脚本和样式的,详见repo。

$npmmstalfaiatdbabel-plugii^.-ii^\poirt--save

(国内镜像:tnpm)

编辑.webpackrc,使babel-plugi^-ii^port插件生效。

(

+"e-KtraBabelPlugi^":[

+['iv^port'1,{"libraryNai^e":"ai^td",,,libraryL)irectoryu:"es","style":"css")]

+]

]

注:dva-cli基于roadhog实现build和dev,更多.webpack匕的

配置详见roadhog#配置

#定义路由

我们要写个应用来先显示产品列表。首先第一步是创建路由,路由可以想象成是

组成应用的不同页面。

新建routecomponentroutes/Products.js,内容如下:

importReactfrokv\'react1;

constProducts=(props)=>(

<h2〉ListofProduct^/h2.>

);

exportdefaultProducts;

添加路由信息到路由表,编辑router.js:

+importProductsfrom'./routes/Products';

+<R.oatepath-11/products"exactCOHA?。八c八2二{Products}/>

然后在浏览器里打开http:〃localhost:8000/#/products,你应该能看到前面定

义的32>标签。

#编写UIComponent

随着应用的发展,你会需要在多个页面分享UI元素(或在一个页面使用多次),

在dva里你可以把这部分抽成component»

我们来编写一个ProductUstcomponent,这样就能在不同的地方显示产品列表了。

新建cow.poM^ts/ProductUst.js文件:

importReactfrom'react'importPspTgpes小。3,prop-types1import{Button,Pope。八

Table}frow\'ai^td'

/关兴

*ReactCo^poM^t有3种定义方式,分别是:

*React.c^eateClass,class和StatelessFuMtioi^alCOM?。八e八士。

*

*推荐最后一种,保持简洁和无状态。

*这是函数,不是Object,没有this作用域,是purefeme力'0八。

*。八De/F八

*绯〃忆出products

*^returns{XML}

*^constructor

*/constProductUst=({0八De/F〜productsy)=>{

constcolumns=[//表格的列

(

title:

dataMdex:'id'

b

(

title:

datal^.dex:

I

(

title:,Actions'j

render:(text,record)=>{

return(

〈Pope。nfi/Mtitle=tDelete?1]。八C。八行m\={()=>{

o八De/F八(wcoKd.id)

W>

〈Butt。八〉Delete〈/Bb(tt。八〉

</Popcoiafirkv\>

)

)

)

return(<Table.dataSource={prodiACts]co/umias={column.s}/>)

)

ProductUst.p^opTypes={

。八Dc/Fn:PropTgpes.fb(八c.isReqjiKed,

products:PropTypes.array.isRequired.

]

//记得导出哦!exportdefaultProductList;

#定义Model

完成UI后,现在开始处理数据和逻辑。

dva通过model的概念把一个领域的模型管理起来,包含同步更新state的

reducers,处理异步逻辑的effects,订阅数据源的subscriptions。

新建modelw\odels/products.js:

exportdefault{

Mkvtespace:'products',

state:[]j

reduces:{

1delete1{payload:id}){

returnstate.ftVterfftem=>itcM.id/==id);

)>

L

这个model里:

•laaMespace表示在全局state上的key

・state是初始值,在这里是空数组

•reducers等同于redux里的reducer,接收action,同步更新state

然后别忘记在Mdexjs里载入他:

//3\.Model

+app.i^odelCreqiAireC./i^odels/product^ydefault);

#connect起来

到这里,我们已经单独完成了model和component,那么他们如何串联起来

呢?

dva提供了connect方法。如果你熟悉redux,这个connect就是

react-redux的connect。

编辑routes/ProductsJs,替换为以卜内容:

importReactFKOM,react,;iimport{eonMCt}from'dva';iwKportProductUstfrom

,../cokv\poMi^ts/ProductL.ist,;

coi^stProducts=({dispatck,products})=>{

fix八ctionkai^.dleDelete(id'){

dispatck([

type:1product^/ddete1j

payload:id.,

1);

)

return(

<div>

52〉ListofProducts</h2.>

<ProductUsto八De/cte={人〃八W/cDc他te}products={products]/>

</div>

);

);

//exportdefaultProducts;exportdefaultconMct(({products))=>({

products,

^(Products);

最后,我们还需要一些初始数据让这个应用run起来。编辑法dexjs:

-constapp=du〃0;+constapp=dva({^ii^itialState:{+products:[+

{'dva^id:1},+{八〃MC:Z八id:2},+力},+});

刷新浏览器,应该能看到以下效果:

ListofProducts

NameActions

dva

antd删除

#构建应用

完成开发并且在开发环境验证之后,就需要部署给我们的用户了。先执行下面的

命令:

$八vuv\build

几秒后,输出应该如下:

>@build/pHvate/tMp/Mgapp

>roadhogbuild

Creatinganoptimizedproductionbuild...

Compiledsuccessfully.

Filesizesaftergzip:

82.48KBdist/i八dex.js

27。Bdist/i八dex.css

build命令会打包所有的资源,包含JavaScript,CSS,webfonts,images,html等。

然后你可以在四t/目录下找到这些文件。

Dva概念

#数据流向

数据的改变发生通常是通过用户交互行为或者浏览器行为(如路由跳转等)触发

的,当此类行为会改变数据的时候可以通过力.spa%发起一个action,如果是同

步行为会直接通过Reduce”改变State,如果是异步行为(副作用)会先触

发Effects然后流向Reducers最终改变State,所以在dva中,数据流向非常清晰

简明,并且思路基本跟开源社区保持一致(也是来自于开源社区)。

connectState

Route

Hdispatch—►

ComponentAction

dispa

#Models

#State

typeState=any

State表示Model的状态数据,通常表现为一个javascript对象(当然它可以

是任何值);操作的时候每次都要当作不可变数据(immutabledata)来对待,

保证每次都是全新对象,没有引用关系,这样才能保证State的独立性,便于

测试和追踪变化。

在dva中你可以通过dva的实例属性看到顶部的state数据,但是通

常你很少会用到:

coiastapp=dva();

c。八so/e」og(4pp._5t。%);//顶部的state数据

#Action

typeAsgncAc'。八=any

Action是一个普通javascript对象,它是改变State的唯一途径。无论是从UI

事件、网络回调,还是WebSocket等数据源所获得的数据,最终都会通过

dispatch函数调用一个action,从而改变对应的数据。action必须带有tgpe属

性指明具体的行为,其它字段可以自定义,如果要发起一个action需要使

用dispatch函数;需要注意的是dispatch是在组件connectModels以后,通过

props传入的。

dispatch([

type:'add1,

});

#dispatch函数

typedispatck=(a:Action)=>Actio八

dispatchingfunction是一个用于触发action的函数,action是改变State的

唯一途径,但是它只描述了一个行为,而dipatch可以看作是触发这个行为的

方式,而Reducer则是描述如何改变数据的。

在dva中,connectModel的组件通过props可以访问到dispatch,可以调

用Model中的Reducer或者Effects,常见的形式如:

d.ispatch({

type:'user/add',//如果在M.ode.1外调用,需要添加namespace

payload:(),//需要传递的信息

1);

#Reducer

typeRedtAceKS,A>=(state:S,action:A)=>S

Reducer(也称为reducingfunction)函数接受两个参数:之前已经累积运算的

结果和当前要被累积的值,返回的是一个新的累积结果。该函数把一个集合归并

成一个单值。

Reducer的概念来自于是函数式编程,很多语言中都有reduceAPL如在

javascript中:

[{x:2}j{y:2L{z:3}J.%duce(ftmctioMprevs八ext){

returnObject.assigNpvev,next);

})//retum{x:l>g:2,z:3}

在dva中,reducers聚合积累的结果是当前model的state对象。通过

actions中传入的值,与当前reducers中的值进行运算获得新的值(也就是新

的state)o需要注意的是Reducer必须是纯函数,所以同样的输入必然得到

同样的输出,它们不应该产生任何副作用。并且,每一次的计算都应该使用

immutabledata,这种特性简单理解就是每次操作都是返回一个全新的数据(独

立,纯净),所以热重载和时间旅行这些功能才能够使用。

#Effect

Effect被称为副作用,在我们的应用中,最常见的就是异步操作。它来自于函数

编程的概念,之所以叫副作用是因为它使得我们的函数变得不纯,同样的输入不

一定获得同样的输出。

dva为了控制副作用的操作,底层引入了redux-sagas做异步流程控制,由于采

用了generator的相关概念,所以将异步转成同步写法,从而将ef能cts转为纯

函数。至于为什么我们这么纠结于纯函数,如果你想了解更多可以阅读Mostly

adequateguidetoFP,或者它的中文译本JS函数式编程指南。

#Subscription

Subscriptions是一种从源获取数据的方法,它来自于elm。

Subscription语义是订阅,用于订阅一个数据源,然后根据条件dispatch需要

的action。数据源可以是当前的时间、服务器的websocket连接、keyboard输

入、geolocation变化、history路由变化等等。

importkeyfrom'keymaster1;

app.Kv\odel({

subscriptions:{

keyEve^t({dispatcK\){

kcyC^upjctrkup',()=>{dispatchatyp^add1})});

)>

}

!);

#Router

这里的路由通常指的是前端路由,由于我们的应用现在通常是单页应用,所以需

要前端代码来控制路由逻辑,通过浏览器提供的HistoryAPI可以监听浏览器url

的变化,从而控制路由相关操作。

dva实例提供了router方法来控制路由,使用的是react-router。

import(RouterjRoute}from'dva/router1;

app.router(({historyj')=>

<Routerh/story={history)>

<R.outepatk\-17nco^poMi^t={Hoi^ePage}/>

</Router>

);

#RouteComponents

在组件设计方法中,我们提到过ContainerComponents,在dva中我们通常

将其约束为RouteComponents,因为在dva中我们通常以页面维度来设计

ContainerComponents。

所以在dva中,通常需要connectModel的组件都是RouteComponents,

组织在/routes/目录下,而/co3po"八区/目录下则是纯组件(Presentational

Components)。

#参考

•reduxdocs

•reduxdocs中文

・MostlyadequateguidetoFP

・JS函数式编程指南

•choodocs

•elm

#例子和脚手架

#官方

•Count:简单计数器

•UserDashboard:用户管理

•AntDesignPro:(Demo),开箱即用的中台前端/设计解决方案

•HackerNews:(Demo),HackerNewsClone

•antd-admin:(Demo),基于antd和dva的后台管理应用

・github-stars:(Demo),GithubStar管理应用

#社区

•AccountSystem:小型库存管理系统

•react-native-dva-starter:集成了dva和react-navigation典型应用场

景的ReactNative实例

Dva图解

作者:至正

原文链接:/flying.ni/the-tower/tvzasn

#示例背景

最常见的Web类示例之一:TodoList=Todolist+Addtodobutton

#图解一:React表示法

按照React官方指导意见,如果多个Component之间要发生交互,那么状态

(即:数据)就维护在这些Component的最小公约父节点上,也即是<A昨/>

<TodoUst/><Todo/>以及<AcWTodo8a/>本身不维持任何State,完全由父节点

<App/>传入props以决定其展现,是一个纯函数的存在形式,即:Pure

Co^pOMint

#图解二:Redux表示法

React只负责页面渲染,而不负责页面逻辑,页面逻辑可以从中单独抽取出来,

变成store

与图一相比,几个明显的改进点:

1.状态及页面逻辑从<A叩/>里面抽取出来,成为独立的store,页面逻辑就

是reducer

2.<Tod.oUst/>及都是PureComponent,通过connect方法

可以很方便地给它俩加一层wrapper从而建立起与store的联系:可

以通过dispatch向store注入action,促使store的状态进行变化,

同时又订阅了store的状态变化,一旦状态有变,被connect的组件也

随之刷新

3.使用dispatch往store发送action的这个过程是可以被拦截的,自然

而然地就可以在这里增加各种Middleware,实现各种自定义功能,eg:

logging

这样一来,各个部分各司其职,耦合度更低,复用度更高,扩展性更好

#图解三:力口入Saga

上面说了,可以使用Middleware拦截action,这样一来异步的网络操作也就

很方便了,做成一个Middleware就行了,这里使用redux-saga这个类库,举

个栗子:

1.点击创建Todo的按钮,发起一个type==addTodo的action

2.saga拦截这个action,发起htt

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论