React学习(一)

2017-01-23  本文已影响0人  小面包屑
框架

根据REACT官网的推荐,选择的框架为 React + Redux + wepack + es6

架构为MVC(Model-View-Controller):
<li>model持有UI要展现的数据(store)</li>
<li>View即UI的展现 (React)</li>
<li>Controller用于控制 (Reducer)</li>


经典前端目录结构
- webapp/               # webapp根目录
  - src/                # 开发目录
    + css/              # css资源目录
    + img/              # webapp图片资源目录
    - js/               # webapp js&jsx资源目录
      - components/     # 标准组件存放目录
          - foo/        # 组件foo
            + css/      # 组件foo的样式
            + js/       # 组件foo的逻辑
            + tmpl/     # 组件foo的模板
            index.js    # 组件foo的入口
          + bar/        # 组件bar
      + lib/            # 第三方纯js库
      ...               # 根据项目需要任意添加的代码目录
    + tmpl/             # webapp前端模板资源目录
    a.html              # webapp入口文件a
    b.html              # webapp入口文件b
  - assets/             # 编译输出目录,即发布目录
    + js/               # 编译输出的js目录
    + img/              # 编译输出的图片目录
    + css/              # 编译输出的css目录
    a.html              # 编译输出的入口a
    b.html              # 编译处理后的入口b
  + mock/               # 假数据目录
  app.js                # 本地server入口
  routes.js             # 本地路由配置
  webpack.config.js     # webpack配置文件
  gulpfile.js           # gulp任务配置
  package.json          # 项目配置
  README.md             # 项目说明

REACT

React 的主要思想是通过构建可复用组件来构建用户界面。所谓组件其实就是 有限状态机,通过状态渲染对应的界面,且每个组件都有自己的生命周期,它规定了组件的状态和方法需要在哪个阶段进行改变和执行。

状态机

生命周期:

// react-lifecycle mixin
import React from 'react';
import ReactDom from 'react-dom';
import LifeCycle from 'react-lifecycle';

const body = document.body;

const MyComponent = React.createClass({
  mixins: [LifeCycle],

  render() {
    console.log('render');
    return null;
  }
});

ReactDom.render(<MyComponent />, body);
ReactDom.unmountComponentAtNode(body);
ReactDom.render(<MyComponent />, body);
ReactDom.render(<MyComponent />, body);

在自定义 React 组件时,根据需要会在组件生命周期的不同阶段实现不同的逻辑。为了查看 组件生命周期的执行顺序,你可以使用 react-lifecycle mixin,将此 mixin 添加到需要观察的组件中,当任何生命周期方法被调用时,都能在控制台观察到对应的生命周期的调用时状态。

生命周期
Redux(数据流)

state

这个对象就像 “Model”,区别是它并没有 setter(修改器方法)。因此其它的代码不能随意修复它,造成难以复现的 bug。
要想更新 state 中的数据,你需要发起一个 action。

{
  todos: [{
    text: 'Eat food',
    completed: true
  }, {
    text: 'Exercise',
    completed: false
  }],
  visibilityFilter: 'SHOW_COMPLETED'
}

action

Action 就是一个普通 JavaScript 对象

{ type: 'ADD_TODO', text: 'Go to swimming pool' }
{ type: 'TOGGLE_TODO', index: 1 }
{ type: 'SET_VISIBILITY_FILTER', filter: 'SHOW_ALL' }

reducer

reducer 只是一个接收 state 和 action,并返回新的 state 的函数。

function visibilityFilter(state = 'SHOW_ALL', action) {
  if (action.type === 'SET_VISIBILITY_FILTER') {
    return action.filter;
  } else {
    return state;
  }
}

function todos(state = [], action) {
  switch (action.type) {
  case 'ADD_TODO':
    return state.concat([{ text: action.text, completed: false }]);
  case 'TOGGLE_TODO':
    return state.map((todo, index) =>
      action.index === index ?
        { text: todo.text, completed: !todo.completed } :
        todo
   )
  default:
    return state;
  }
}

webpack

官网对webpack的定义是MODULE BUNDLER,他的目的就是把有依赖关系的各种文件打包成一系列的静态资源。

Paste_Image.png

每个项目下都必须配置有一个 webpack.config.js

var webpack = require('webpack');
var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js');
 
module.exports = {
    //插件项
    plugins: [commonsPlugin],
    //页面入口文件配置
    entry: {
        index : './src/js/page/index.js'
    },
    //入口文件输出配置
    output: {
        path: 'dist/js/page',
        filename: '[name].js'
    },
    module: {
        //加载器配置
        loaders: [
            { test: /\.css$/, loader: 'style-loader!css-loader' },
            { test: /\.js$/, loader: 'jsx-loader?harmony' },
            { test: /\.scss$/, loader: 'style!css!sass?sourceMap'},
            { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'}
        ]
    },
    //其它解决方案配置
    resolve: {
        root: 'E:/github/flux-example/src', //绝对路径
        extensions: ['', '.js', '.json', '.scss'],
        alias: {
            AppStore : 'js/stores/AppStores.js',
            ActionType : 'js/actions/ActionType.js',
            AppAction : 'js/actions/AppAction.js'
        }
    }
};
ES6

ECMAScript 6.0(简称ES6)是JavaScript语言的下一代标准.

Bable

能够实现 ES6 到 ES5 的代码转换多亏了 Babel (以前叫 6to5) 以及 Traceur 之类的项目。这些转换器 (更准确地说是源代码到源代码的编译器) 可以把你写的符合 ECMAScript 6 标准的代码完美地转换为 ECMAScript 5 标准的代码,并且可以确保良好地运行在所有主流 JavaScript 引擎中。

ES6语法例子

import 'core-js/shim';

export default class Person {

  constructor( name ) {
    this.name = name;
  }

  sayHello() {
    return `Hello ${ this.name }!`;
  }

  sayHelloThreeTimes() {
    let hello = this.sayHello();
    return `${ hello } `.repeat(3);
  }
}

参考资料:
react
http://segmentfault.com/a/1190000003940416?utm_source=APP&utm_medium=iOS&utm_campaign=socialShare&from=groupmessage&isappinstalled=1
http://top.jobbole.com/15576/

react-router
https://github.com/rackt/react-router

redux
http://camsong.github.io/redux-in-chinese/
https://github.com/rackt/redux examples

redux-router
https://github.com/acdlite/redux-router examples

redux-form
https://github.com/erikras/redux-form

babel
es6
http://es6.ruanyifeng.com/#docs/intro

webpack
http://segmentfault.com/a/1190000003499526
http://segmentfault.com/a/1190000002551952
https://blog.crazycoder.cc/p/react-using-webpack

fetch
http://www.thinksaas.cn/group/topic/396019/
http://www.tuicool.com/articles/QZBJ7zJ

上一篇下一篇

猜你喜欢

热点阅读