React最佳实践(一)

来源:互联网 发布:mac上可以玩什么网游 编辑:程序博客网 时间:2024/05/22 00:51

前言

一个完整的React项目,包含许多优秀的技术库支持,它的数据流,可以通过flux/redux管理,它的路由配置:react-router,它的包管理、测试以及组件编写(ES6),接下来会对这些相关技术做一些深入的了解和整理,持续更新中。

1. WebPacket

  • webPacket

    webpacke是一个前端模块管理和打包工具,通过使用Webpack,能够像Node.js一样处理依赖关系,然后解析出模块之间的依赖,将代码打包。

    webpacket将项目中用到的一切静态资源都视为模块,模块之间互相依赖。webpacket对其进行统一的管理以及打包发布。
    这里写图片描述

    webpack-dev-server是一个小型的node.js Express服务器,它使用webpack-dev-middleware中间件来为通过webpack打包生成的资源文件提供Web服务。它还有一个通过Socket.IO连接着webpack-dev-server服务器的小型运行时程序。webpack-dev-server发送关于编译状态的消息到客户端,客户端根据消息作出响应。
    简单来说,webpack-dev-server就是一个小型的静态文件服务器。使用它,可以为webpack打包生成的资源文件提供Web服务。

    这里写图片描述![](http://img.blog.csdn.net/20160410212740977)

    • NPM (http://www.runoob.com/nodejs/nodejs-npm.html‘>详情参考)

      NPM的全称是Node Package Manager,它是Nodejs的包管理器。Nodejs自身提供了基本的模块。但是在这些基本模块上开发实际应用需要较多的工作。NPM上已经有了很多Nodejs库或框架,这些库从各个方面可以帮助Nodejs的开发者完成较为复杂的应用。     

      package.json

      Package.json 属性说明:name - 包名。version - 包的版本号。description - 包的描述。homepage - 包的官网 url 。author - 包的作者姓名。contributors - 包的其他贡献者姓名。dependencies - 依赖包列表。如果依赖包没有安装,npm 会自动将依赖包安装在 node_module 目录下。repository - 包代码存放的地方的类型,可以是 git 或 svn,git 可在 Github 上。main - main 字段是一个模块ID,它是一个指向你程序的主要项目。就是说,如果你包的名字叫 express,然后用户安装它,然后require("express")。keywords - 关键字
  • webPacket 配置

    • 来看一个最简单的webPacket配置: webPacket.config.js

      module.exports = {  entry:[    './app/main.js'             //定义打包后的入口文件  ],  output: {                     //定义输出文件位置    path: __dirname + '/assets/',     //打包文件存放绝对路径    publicPath: "/assets/",             //网站运行时的访问路径    filename: 'bundle.js'               //打包后的文件名  }};
    • webPacket 模块加载器(Loaders)

      安装加载器命令:

      $ npm install xxx-loader --save例如: 安装css加载器npm install css-loader style-loader --save-dev 

      安装后,会自动同步到package.json文件中。

      在webpack.config.js中配置loader:

      module: {    loaders: [        {test: /\.css$/, loaders: ['style', 'css']},        {test: /\.less$/, loaders: ['style', 'css', 'less']}        ]}

      其中,test里包含一个正则,包含需要匹配的文件。loaders是一个数组,包含要处理这些程序的loaders,这里要注意loaders处理的顺序是从右往左的。

      也可以用webpack来处理图片和静态文件

      安装url-loadernpm install url-loader --save-dev配置config文件{    test: /\.(png|jpg)$/,    loader: 'url?limit=40000'  //limit参数,当图片大小超过这个限制的时候,会启用base64编码图片}

      添加ES6支持:
      可以通过babel配置,添加对ES6语法的支持

2. Redux

React的核心是使用组件定义界面的表现,是一个View层的前端库,那么在使用React的时候我们通常还需要一套机制去管理组件与组件之间,组件与数据模型之间的通信。

  • 介绍

    随着Javascript单页应用开发日趋复杂,javascript需要管理比任何时候都要多的状态,管理这些不断变化的state十分困难。**state在什么时候,由于什么原因,如何变化已然不受控制。**Redux就是为了处理React中state数据的问题而出现的,它试图让state的变换变得可预测。

  • 三大原则

    1. 单一数据源

      整个应用的state被储存在一颗object tree中,并且这个object tree只存在于唯一一个store中。

    2. state是只读的

      唯一改变state的方法就是触发action,action是一个用于描述已发生事件的普通对象。

      这样就确保了所有state的修改都被集中化处理,视图和网络请求不能直接修改state,只能表达想要修改的意图。

    3. 使用纯函数进行修改

      为了描述action如何改变state tree,需要编写reducers.

      Reducer只是一些纯函数,它接受先前的state和action,并返回新的state。

  • redux和flux

    flux是Facebook建立客户端web应用的前端架构,它通过利用一个单向的数据流补充了React的组合视图组件。

    Redux 的灵感来源于 Flux 的几个重要特性。和 Flux 一样,Redux 规定,将模型的更新逻辑全部集中于一个特定的层(Flux 里的 store,Redux 里的 reducer)。Flux 和 Redux 都不允许程序直接修改数据,而是用一个叫作 “action” 的普通对象来对更改进行描述。

    不同于flux,redux没有调度器。它依赖纯函数来替代事件处理器。纯函数构建简单,也无需用额外的实体来管理它们。

  • Redux

    1. Action

      Action是把数据从应用传到store的有效载荷,是store数据的唯一来源。

      Action本质是javascript普通对象。Redux中的action是纯函数,没有任何副作用。

    2. Reduce

      Action只是描述了有事情发生这一事实,并未指明应用如何更新state,更新state是reducer要做的事情。

      应用所有的state都被保存在一个单一的对象中(state树)。

      对于Action和Reducer,它们有明确的分工
      Action -> 干了什么,数据如何变化
      Reducer -> 更新state状态

    3. Store

      我们已经知道action用来描述发生了什么,reducers根据action更新state。

      Store就是把他们联系到一起的对象,Store有以下职责:

      • 维持应用的state
      • 提供getState( ) 方法获取state
      • 提供dispatch(action) 方法更新state
      • 通过subscribe(listener)方法注册监听器

      Reduce应用只有一个单一的store, 需要拆分处理数据的逻辑时,用render组合而不是创建多个store。

    4. 数据流

      严格的单向数据流是Redux架构设计的核心。这意味着应用中的所有数据都遵循着相同的生命周期,使应用变得更加可预测和容易理解。

      Redux应用中数据的声明周期遵循下面四个步骤:

      1. 调用store.dispatch(action)

        Action就是一个描述发生了什么的普通对象:

         { type: 'LIKE_ARTICLE', articleId: 42 }; { type: 'FETCH_USER_SUCCESS', response: { id: 3, name: 'Mary' } }; { type: 'ADD_TODO', text: 'Read the Redux docs.'};

        可以在任何地方调用store.dispatch(action)

      2. Redux store 调用传入的reducer函数

        Store会把两个参数传入reducer: 当前的state树和action。

        function getClientHistorySuccess (state, action) {    return _.extend({}, state, {        histories: action.histories,        getHistoryLoading: false    });}

        注意reducer是纯函数。它仅仅用作计算下一个state,它应该是完全可预测的:多次传入相同的输入必须产生相同的输出。它不应做有副作用的操作,如 API 调用或路由跳转。这些应该在 dispatch action 前发生。

      3. 根 reducer 应该把多个子 reducer 输出合并成一个单一的 state 树。

        根 reducer 的结构完全由你决定。Redux 原生提供combineReducers()辅助函数,来把根 reducer 拆分成多个函数,用于分别处理 state 树的一个分支。

      4. Redux store 保存了根 reducer 返回的完整 state 树。

  • 搭配React

    1. beginning

      Redux 默认并不包含 React 绑定库,需要单独安装。

      npm install --save react-redux
    2. 容器组件和展示组件

      Redux 的 React 绑定库包含了 容器组件和展示组件相分离 的开发思想。

      明智的做法是只在最顶层组件(如路由操作)里使用 Redux。其余内部组件仅仅是展示性的,所有数据都通过 props 传入。

      容器组件展示组件 Location最顶层,路由处理中间和子组件 Awesome of redux是否 读取数据从Redux获取state从props获取数据 修改数据向Redux派发actions从props调用回调函数
    3. 接下来就是具体的组件编写工作,主要的组件编写完成后,需要连接到redux

      首先,需要获取从之前安装好的 react-redux 提供的 Provider,并且在渲染之前将根组件包装进 。

      let rootElement = document.getElementById('root')render(  <Provider store={store}>    <App />  </Provider>,  rootElement)

      这使得 store 能为下面的组件所用。

      接着,通过 react-redux 提供的 connect() 方法将包装好的组件连接到Redux。尽量只做一个顶层的组件,或者 route 处理。
      任何一个从 connect() 包装好的组件都可以得到一个 dispatch 方法作为组件的 props,以及得到全局 state 中所需的任何内容。 connect() 的唯一参数是 selector。此方法可以从 Redux store 接收到全局的 state,然后返回组件中需要的 props。最简单的情况下,可以返回一个初始的 state (例如,返回认证方法),但最好先将其进行转化。

3. react-route

解决复杂的URL和层级组件之间的映射关系是React Router的核心。我们使用声明式的方式引入路由。使用JSX方式来进行路由的配置。这样就可以通过属性的方式来配置页面视图的层级关系。

  • 路由配置

    var Router = require('react-router');var Route = Router.Route;var routes = (  <Route handler={App}>    <Route path="about" handler={About}/>    <Route path="inbox" handler={Inbox}/>  </Route>);

(needs update: react-route semanticUI)

0 0
原创粉丝点击