├── images └── lifecycle.png ├── 02、jsx ├── src │ ├── main.js │ ├── index.html │ └── jsx │ │ └── App.jsx ├── package.json ├── webpack.config.js └── README.md ├── 09、ref ├── src │ ├── main.js │ ├── index.html │ └── jsx │ │ ├── KindsOfRefs.jsx │ │ ├── findDomNode1.jsx │ │ ├── findDomNode2.jsx │ │ └── RefApp.jsx ├── README.md ├── package.json └── webpack.config.js ├── 10、key ├── src │ ├── main.js │ ├── index.html │ └── jsx │ │ └── KeyApp.jsx ├── README.md ├── package.json └── webpack.config.js ├── 01、environment_setup ├── src │ ├── main.js │ ├── index.html │ └── jsx │ │ └── App.jsx ├── package.json ├── webpack.config.js └── README.md ├── 14、betterReact ├── Readme.md ├── Children.js └── MapApp.js ├── 07、forms ├── src │ ├── index.html │ ├── main.js │ └── jsx │ │ ├── SimpleFormApp.jsx │ │ └── ComplexFormApp.jsx ├── README.md ├── package.json └── webpack.config.js ├── 12、redux ├── src │ ├── index.html │ ├── actions │ │ └── actions.js │ ├── components │ │ ├── Todo.js │ │ ├── TodoList.js │ │ └── AddTodo.js │ ├── main.js │ ├── reducers │ │ └── reducers.js │ └── App.js ├── README.md ├── webpack.config.js └── package.json ├── 03、components ├── src │ ├── index.html │ ├── jsx │ │ ├── StatelessApp.jsx │ │ ├── FunctionApp.jsx │ │ ├── HocApp.jsx │ │ ├── ReUseableApp.js │ │ └── StatefulApp.jsx │ └── main.js ├── package.json ├── webpack.config.js └── README.md ├── 08、events ├── src │ ├── index.html │ ├── main.js │ └── jsx │ │ ├── SimpleEventApp.jsx │ │ └── ChildEventsApp.jsx ├── README.md ├── package.json └── webpack.config.js ├── 11、router ├── src │ ├── index.html │ ├── jsx │ │ ├── Home.jsx │ │ ├── About.jsx │ │ ├── Contact.jsx │ │ └── App.jsx │ └── main.js ├── README.md ├── package.json └── webpack.config.js ├── 04、state_props ├── src │ ├── index.html │ ├── jsx │ │ ├── PropsApp.jsx │ │ ├── DefaultPropsApp.jsx │ │ ├── StateApp.jsx │ │ ├── CustomValidat.jsx │ │ ├── StateAndPropsApp.jsx │ │ ├── ValidatingPropsApp.jsx │ │ └── ContactsApp.jsx │ ├── public │ │ └── contacts.json │ └── main.js ├── package.json ├── webpack.config.js └── README.md ├── 05、componentapi ├── src │ ├── index.html │ ├── jsx │ │ ├── ForceUpdateApp.jsx │ │ ├── FindDomNodeApp.jsx │ │ └── SetStateApp.jsx │ └── main.js ├── README.md ├── package.json └── webpack.config.js ├── 06、lifecyclemethods ├── src │ ├── index.html │ ├── main.js │ └── jsx │ │ └── App.jsx ├── package.json ├── webpack.config.js └── README.md ├── 13、animations ├── src │ ├── index.html │ ├── main.js │ ├── styles │ │ └── style.css │ └── jsx │ │ └── AnimationApp.jsx ├── README.md ├── package.json └── webpack.config.js ├── LICENSE ├── 00、es6-notes ├── 04-Object对象.md ├── README.md ├── 02-class类.md ├── 07-Modules模块化.md ├── 05-array、map、set.md ├── 06-Promise.md ├── 01-变量和参数.md └── 03-FunctionalJS函数.md └── README.md /images/lifecycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mqy1023/react-with-es6/HEAD/images/lifecycle.png -------------------------------------------------------------------------------- /02、jsx/src/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './jsx/App.jsx'; 4 | 5 | ReactDOM.render(, document.getElementById('app')) -------------------------------------------------------------------------------- /09、ref/src/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | import App from './jsx/RefApp.jsx'; 5 | 6 | ReactDOM.render(, document.getElementById('app')); -------------------------------------------------------------------------------- /10、key/src/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | import App from './jsx/KeyApp.jsx'; 5 | 6 | ReactDOM.render(, document.getElementById('app')); -------------------------------------------------------------------------------- /01、environment_setup/src/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './jsx/App.jsx'; 4 | 5 | ReactDOM.render(, document.getElementById('app')) -------------------------------------------------------------------------------- /14、betterReact/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | ## 更好方式编写React 3 | 4 | #### 一、MapApp中无状态组件 5 | 6 | #### 二、Children 7 | 遍历父组件的子组件,使用React.Children.map()替代this.props.children.map()【因为只有一个子组件时,this.props.children为一个对象而非数组】 8 | -------------------------------------------------------------------------------- /02、jsx/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | React App 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /07、forms/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | React App 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /09、ref/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | React App 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /10、key/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | React App 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /12、redux/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | React App 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /03、components/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | React App 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /08、events/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | React App 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /11、router/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | React App 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /04、state_props/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | React App 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /05、componentapi/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | React App 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /01、environment_setup/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | React App 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /06、lifecyclemethods/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | React App 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /13、animations/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | React App 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /13、animations/src/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom'; 3 | import App from './jsx/AnimationApp.jsx'; 4 | import './styles/style.css'; //引入CSS样式 5 | 6 | ReactDOM.render(, document.getElementById('app')); 7 | -------------------------------------------------------------------------------- /12、redux/src/actions/actions.js: -------------------------------------------------------------------------------- 1 | export const ADD_TODO = 'ADD_TODO' 2 | 3 | let nextTodoId = 0; 4 | 5 | export function addTodo(text) { 6 | return { 7 | type: ADD_TODO, 8 | id: nextTodoId++, 9 | text 10 | }; 11 | } -------------------------------------------------------------------------------- /07、forms/src/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | //import App from './jsx/SimpleEventApp.jsx'; 5 | 6 | import App from './jsx/ComplexFormApp.jsx'; 7 | 8 | ReactDOM.render(, document.getElementById('app')); -------------------------------------------------------------------------------- /08、events/src/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | //import App from './jsx/SimpleEventApp.jsx'; 5 | 6 | import App from './jsx/ChildEventsApp.jsx'; 7 | 8 | ReactDOM.render(, document.getElementById('app')); -------------------------------------------------------------------------------- /11、router/src/jsx/Home.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class Home extends React.Component { 4 | render() { 5 | return ( 6 |
7 |

Home...

8 |
9 | ) 10 | } 11 | } 12 | 13 | export default Home; -------------------------------------------------------------------------------- /11、router/src/jsx/About.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class About extends React.Component { 4 | render() { 5 | return ( 6 |
7 |

About...

8 |
9 | ) 10 | } 11 | } 12 | 13 | export default About; -------------------------------------------------------------------------------- /01、environment_setup/src/jsx/App.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class App extends React.Component { 4 | render() { 5 | return ( 6 |
7 | Hello World!!! 8 |
9 | ); 10 | } 11 | } 12 | 13 | export default App; -------------------------------------------------------------------------------- /12、redux/src/components/Todo.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react' 2 | 3 | export default class Todo extends Component { 4 | render() { 5 | return ( 6 |
  • 7 | {this.props.text} 8 |
  • 9 | ) 10 | } 11 | } -------------------------------------------------------------------------------- /10、key/README.md: -------------------------------------------------------------------------------- 1 | ## 启动步骤 2 | * 1、npm install 3 | * 2、npm start,然后可以在浏览器中打开localhost:8888 4 | 或者npm run prod,然后可以到dist目录下打开index.html
    5 | 或者直接webpack,然后可以到dist目录下打开index.html 6 | 7 | ## React key 8 | 9 | **1、App.jsx**
    10 | 给每个组件设置key属性(必须唯一性),在动态创建组件或用户修改List组件的情况,能保持组件的唯一身份 11 | -------------------------------------------------------------------------------- /11、router/src/jsx/Contact.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class Contact extends React.Component { 4 | render() { 5 | return ( 6 |
    7 |

    Contact...

    8 |
    9 | ) 10 | } 11 | } 12 | 13 | export default Contact; -------------------------------------------------------------------------------- /06、lifecyclemethods/src/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | import App from './jsx/App.jsx'; 5 | 6 | ReactDOM.render(, document.getElementById('app')); 7 | 8 | setTimeout(() => { 9 | ReactDOM.unmountComponentAtNode(document.getElementById('app'));}, 10000); -------------------------------------------------------------------------------- /12、redux/README.md: -------------------------------------------------------------------------------- 1 | ## 启动步骤 2 | * 1、npm install 3 | * 2、npm start,然后在浏览器中打开localhost:8888 4 | 5 | ## react router路由 6 | 7 | ### step1:安装Redux 8 | ```bash 9 | npm install --save redux react-redux 10 | ``` 11 | ### step2:创建——actions、reducers、components 12 | 详情查看项目目录分布和源码 13 | 14 | ### step3:添加Router路由 15 | -------------------------------------------------------------------------------- /04、state_props/src/jsx/PropsApp.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class App extends React.Component { 4 | render() { 5 | return ( 6 |
    7 |

    {this.props.headerProp}

    8 |

    {this.props.contentProp}

    9 |
    10 | ); 11 | } 12 | } 13 | 14 | export default App; -------------------------------------------------------------------------------- /08、events/README.md: -------------------------------------------------------------------------------- 1 | ## 启动步骤 2 | * 1、npm install 3 | * 2、npm start,然后可以在浏览器中打开localhost:8888
    4 | 或者npm run prod,然后可以到dist目录下打开index.html
    5 | 或者直接webpack,然后可以到dist目录下打开index.html 6 | 7 | ## React Event事件 8 | 9 | **1、SimpleEventApp.jsx**
    10 | onClick点击事件触发updateState函数
    11 | 12 | 13 | **2、App.jsx**
    14 | 通过子组件来更新父组件,需要父组件中将updateState函数当做updateStateProp属性传给子组件 15 | -------------------------------------------------------------------------------- /03、components/src/jsx/StatelessApp.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class App extends React.Component { 4 | render() { 5 | return ( 6 |
    7 |
    8 | 9 |
    10 | ); 11 | } 12 | } 13 | 14 | const Header = () =>

    Header

    15 | 16 | const Content = () =>

    Content

    17 | 18 | export default App; 19 | -------------------------------------------------------------------------------- /12、redux/src/components/TodoList.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react' 2 | import Todo from './Todo' 3 | 4 | export default class TodoList extends Component { 5 | render() { 6 | return ( 7 |
      8 | {this.props.todos.map(todo => 9 | 10 | )} 11 |
    12 | ) 13 | } 14 | } -------------------------------------------------------------------------------- /02、jsx/src/jsx/App.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class App extends React.Component { 4 | render() { 5 | return ( 6 |
    7 |

    Header

    8 |

    Content

    9 |

    This is the content!!!

    10 |

    This is the content have attribute!!!

    11 |
    12 | ); 13 | } 14 | } 15 | 16 | export default App; -------------------------------------------------------------------------------- /12、redux/src/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import { render } from 'react-dom' 4 | import { createStore } from 'redux' 5 | import { Provider } from 'react-redux' 6 | 7 | import App from './App' 8 | import todoApp from './reducers/reducers' 9 | 10 | let store = createStore(todoApp) 11 | 12 | let rootElement = document.getElementById('app') 13 | 14 | render( 15 | 16 | 17 | , 18 | rootElement 19 | ) -------------------------------------------------------------------------------- /09、ref/README.md: -------------------------------------------------------------------------------- 1 | ## 启动步骤 2 | * 1、npm install 3 | * 2、npm start,然后可以在浏览器中打开localhost:8888
    4 | 或者npm run prod,然后可以到dist目录下打开index.html
    5 | 或者直接webpack,然后可以到dist目录下打开index.html 6 | 7 | ## React Refs 8 | 9 | **1、App.jsx**
    10 | ref相当于元素一个引用,一般仅在需要DOM操作或添加方法到组件的情况下使用. 11 | 12 | 如例子中,将ref = "myInput"的DOM节点focus聚焦 13 | 14 | #### kindsOfRefs 15 | refs的两种使用方式,建议使用`ref={ node => this.refsA = node }` 16 | 17 | #### 是否是最外一层组件的findDOMNode两种方式 18 | 19 | * findDOMNode1 20 | * findDOMNode2 21 | -------------------------------------------------------------------------------- /13、animations/README.md: -------------------------------------------------------------------------------- 1 | ## 启动步骤 2 | * 1、npm install 3 | * 2、npm start,然后可以在浏览器中打开localhost:8888
    4 | 或者npm run prod,然后可以到dist目录下打开index.html
    5 | 或者直接webpack,然后可以到dist目录下打开index.html 6 | 7 | ## React Animations动画 8 | 9 | ### step1: 安装React CSS Transitions Group 10 | ```bash 11 | npm install --save react-addons-css-transition-group 12 | ``` 13 | ### step2: 引入CSS样式 14 | * 1、npm install --save-dev style-loader css-loader //安装css加载器 15 | * 2、import './styles/style.css'; //在入口main.js中引入CSS样式 16 | -------------------------------------------------------------------------------- /04、state_props/src/jsx/DefaultPropsApp.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class App extends React.Component { 4 | render() { 5 | return ( 6 |
    7 |

    {this.props.headerProp}

    8 |

    {this.props.contentProp}

    9 |
    10 | ); 11 | } 12 | } 13 | 14 | App.defaultProps = { 15 | headerProp: "Header from default props...", 16 | contentProp: "Content from default props..." 17 | } 18 | 19 | export default App; -------------------------------------------------------------------------------- /11、router/README.md: -------------------------------------------------------------------------------- 1 | ## 启动步骤 2 | * 1、npm install 3 | * 2、npm start,然后在浏览器中打开localhost:8888 4 | 5 | ## react router路由 6 | 7 | ### step1:安装React Router 8 | ```bash 9 | npm install --save react-router 10 | ``` 11 | ### step2:创建组件 12 | 创建四个组件,其中App组件当做一个tab菜单,其他Home、About、Contact三个组件随路由的更变而渲染 13 | 14 | ### step3:添加Router路由 15 | 16 | ## 参考链接 17 | * [React Router 使用教程](http://www.ruanyifeng.com/blog/2016/05/react_router.html) 18 | * [react-router-tutorial](https://github.com/reactjs/react-router-tutorial/tree/master/lessons) 19 | -------------------------------------------------------------------------------- /07、forms/README.md: -------------------------------------------------------------------------------- 1 | ## 启动步骤 2 | * 1、npm install 3 | * 2、npm start,然后可以在浏览器中打开localhost:8888. 4 | 5 | 或者npm run prod,然后可以到dist目录下打开index.html. 6 | 7 | 或者直接webpack,然后可以到dist目录下打开index.html 8 | 9 | ## React Forms表格 10 | 11 | * **1、SimpleEventApp.jsx**
    12 | 通过setState()方法更新state,当表单输入更改会调用onChange()方法
    13 | 14 | * **2、App.jsx**
    15 | 使用Form表单的子组件,子组件中input元素的onChange方法触发父组件的updateStateProp属性,该属性在父组件中调用updateState函数更新state状态,
    16 | 然后父组件通过myDataProp属性传给子组件,更新子组件中input和h3标签的value值(父组件中将updateState函数当做updateStateProp属性传给子组件) 17 | -------------------------------------------------------------------------------- /04、state_props/src/jsx/StateApp.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class App extends React.Component { 4 | constructor(props) { 5 | super(props); 6 | 7 | this.state = { 8 | header: "Header from state...", 9 | "content": "Content from state..." 10 | } 11 | } 12 | 13 | render() { 14 | return ( 15 |
    16 |

    {this.state.header}

    17 |

    {this.state.content}

    18 |
    19 | ); 20 | } 21 | } 22 | 23 | export default App; -------------------------------------------------------------------------------- /11、router/src/jsx/App.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router' 3 | 4 | class App extends React.Component { 5 | render() { 6 | return ( 7 |
    8 |
      9 |
    • Home
    • 10 |
    • About
    • 11 |
    • Contact
    • 12 |
    13 | {this.props.children} 14 |
    15 | ) 16 | } 17 | } 18 | 19 | export default App; -------------------------------------------------------------------------------- /12、redux/src/components/AddTodo.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react' 2 | 3 | export default class AddTodo extends Component { 4 | render() { 5 | return ( 6 |
    7 | 8 | 9 |
    10 | ) 11 | } 12 | 13 | handleClick(e) { 14 | const node = this.refs.input 15 | const text = node.value.trim() 16 | this.props.onAddClick(text) 17 | node.value = '' 18 | } 19 | } -------------------------------------------------------------------------------- /03、components/src/jsx/FunctionApp.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | //### 1、无状态函数式组件也支持设置默认的Props类型与值 4 | //ES6设置默认参数值 5 | // const Text = ({ children = 'Hello World!'}) => 6 | //

    {children}

    7 | // //无状态函数式组件的写法也是支持设置默认的Props类型与值的: 8 | // Text.propTypes = { children: React.PropTypes.string }; 9 | // App.defaultProps = { children: 'Hello World!' }; //默认值另外一种形式 10 | 11 | 12 | //### 2、无状态的组件函数中,也可以访问Context 13 | const Text = (props, context) => 14 |

    {props.children}

    ; 15 | Text.contextTypes = { 16 | fontFamily: React.PropTypes.string 17 | }; 18 | 19 | export default Text; 20 | -------------------------------------------------------------------------------- /04、state_props/src/jsx/CustomValidat.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class CustomValidate extends React.Component { 4 | render() { 5 | return 6 | } 7 | } 8 | 9 | const Title = (props) => <h1>Title: {props.text}</h1> 10 | 11 | Title.propTypes = { 12 | text(props, propName, component) { 13 | if (!(propName in props)) { 14 | return new Error(`missing ${propName}`); // 没找到属性 15 | } 16 | if (props[propName].length < 6) { 17 | return new Error(`${propName} was too short`); // 属性值的长度太短 18 | } 19 | } 20 | } 21 | 22 | export default CustomValidate; 23 | -------------------------------------------------------------------------------- /05、componentapi/src/jsx/ForceUpdateApp.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class App extends React.Component { 4 | constructor() { 5 | super(); 6 | this.forceUpdateHandler = this.forceUpdateHandler.bind(this); 7 | }; 8 | 9 | forceUpdateHandler() { 10 | this.forceUpdate(); 11 | }; 12 | 13 | render() { 14 | return ( 15 | <div> 16 | <button onClick = {this.forceUpdateHandler}>FORCE UPDATE</button> 17 | <h4>Random number: {Math.random()}</h4> 18 | </div> 19 | ); 20 | } 21 | } 22 | 23 | export default App; -------------------------------------------------------------------------------- /04、state_props/src/public/contacts.json: -------------------------------------------------------------------------------- 1 | { 2 | "datas":[ 3 | { 4 | "name": "Cassio Zen", 5 | "email": "cassiozen@gmail.com" 6 | }, 7 | { 8 | "name": "Dan Abramov", 9 | "email": "gaearon@somewhere.com" 10 | }, 11 | { 12 | "name": "Pete Hunt", 13 | "email": "floydophone@somewhere.com" 14 | }, 15 | { 16 | "name": "Paul O’Shannessy", 17 | "email": "zpao@somewhere.com" 18 | }, 19 | { 20 | "name": "Ryan Florence", 21 | "email": "rpflorence@somewhere.com" 22 | }, 23 | { 24 | "name": "Sebastian Markbage", 25 | "email": "sebmarkbage@here.com" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /05、componentapi/README.md: -------------------------------------------------------------------------------- 1 | ## 启动步骤 2 | * 1、npm install 3 | * 2、npm start,然后可以在浏览器中打开localhost:8888 <br/> 4 | 或者npm run prod,然后可以到dist目录下打开index.html <br/> 5 | 或者直接webpack,然后可以到dist目录下打开index.html 6 | 7 | ## React Components API介绍 8 | 本文介绍了组件API: 9 | * setState() 10 | * forceUpdate 11 | * ReactDOM.findDOMNode() 12 | 在es6语法中需要手动bind绑定this,将在下面的例子中看到使用this.method.bind(this)绑定 13 | 14 | ### 设置状态setState() 15 | setState()方法用于更新组件state, 在原state状态基础上更改state 16 | 例子:每点击一次按钮,增加一个“setState...” 17 | 18 | ### 强制更新ForceUpdate 19 | 可以使用forceUpdate()强制更新组件 20 | 21 | ### 查找DOM节点Find Dom Node 22 | 可以使用`ReactDOM.findDOMNode()``方法操作真正的`DOM` 23 | 例子:点击按钮,查找`id`为`myDiv`的`DOM`节点,改变成绿色 24 | -------------------------------------------------------------------------------- /08、events/src/jsx/SimpleEventApp.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class App extends React.Component { 4 | 5 | constructor(props) { 6 | super(props); 7 | 8 | this.state = { 9 | data: 'Initial data...' 10 | } 11 | 12 | this.updateState = this.updateState.bind(this); 13 | 14 | }; 15 | 16 | updateState() { 17 | this.setState({data: 'Data updated...'}) 18 | } 19 | 20 | render() { 21 | return ( 22 | <div> 23 | <button onClick = {this.updateState}>CLICK</button> 24 | <h4>{this.state.data}</h4> 25 | </div> 26 | ); 27 | } 28 | } 29 | 30 | export default App; -------------------------------------------------------------------------------- /02、jsx/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "environment_setup", 3 | "version": "1.0.0", 4 | "description": "react enviroment set up", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --hot", 8 | "prod": "webpack -p" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "react": "^15.1.0", 15 | "react-dom": "^15.1.0", 16 | "webpack": "^1.13.1", 17 | "webpack-dev-server": "^1.14.1" 18 | }, 19 | "devDependencies": { 20 | "babel-core": "^6.10.4", 21 | "babel-loader": "^6.2.4", 22 | "babel-preset-es2015": "^6.9.0", 23 | "babel-preset-react": "^6.5.0", 24 | "html-webpack-plugin": "^2.21.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /09、ref/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "environment_setup", 3 | "version": "1.0.0", 4 | "description": "react enviroment set up", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --hot", 8 | "prod": "webpack -p" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "react": "^15.1.0", 15 | "react-dom": "^15.1.0", 16 | "webpack": "^1.13.1", 17 | "webpack-dev-server": "^1.14.1" 18 | }, 19 | "devDependencies": { 20 | "babel-core": "^6.10.4", 21 | "babel-loader": "^6.2.4", 22 | "babel-preset-es2015": "^6.9.0", 23 | "babel-preset-react": "^6.5.0", 24 | "html-webpack-plugin": "^2.21.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /10、key/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "environment_setup", 3 | "version": "1.0.0", 4 | "description": "react enviroment set up", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --hot", 8 | "prod": "webpack -p" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "react": "^15.1.0", 15 | "react-dom": "^15.1.0", 16 | "webpack": "^1.13.1", 17 | "webpack-dev-server": "^1.14.1" 18 | }, 19 | "devDependencies": { 20 | "babel-core": "^6.10.4", 21 | "babel-loader": "^6.2.4", 22 | "babel-preset-es2015": "^6.9.0", 23 | "babel-preset-react": "^6.5.0", 24 | "html-webpack-plugin": "^2.21.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /02、jsx/webpack.config.js: -------------------------------------------------------------------------------- 1 | var HtmlWebpackPlugin = require('html-webpack-plugin') 2 | var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({ 3 | template: __dirname + '/src/index.html', 4 | filename: 'index.html', 5 | inject: 'body' 6 | }); 7 | 8 | var config = { 9 | entry: './src/main.js', 10 | 11 | output: { 12 | path:'./dist', 13 | filename: 'index.js', 14 | }, 15 | 16 | devServer: { 17 | inline: true, 18 | port: 8888 19 | }, 20 | 21 | module: { 22 | loaders: [{test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel', query: {presets: ['es2015', 'react']}}] 23 | }, 24 | plugins: [HTMLWebpackPluginConfig] 25 | } 26 | 27 | module.exports = config; -------------------------------------------------------------------------------- /07、forms/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "environment_setup", 3 | "version": "1.0.0", 4 | "description": "react enviroment set up", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --hot", 8 | "prod": "webpack -p" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "react": "^15.1.0", 15 | "react-dom": "^15.1.0", 16 | "webpack": "^1.13.1", 17 | "webpack-dev-server": "^1.14.1" 18 | }, 19 | "devDependencies": { 20 | "babel-core": "^6.10.4", 21 | "babel-loader": "^6.2.4", 22 | "babel-preset-es2015": "^6.9.0", 23 | "babel-preset-react": "^6.5.0", 24 | "html-webpack-plugin": "^2.21.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /07、forms/webpack.config.js: -------------------------------------------------------------------------------- 1 | var HtmlWebpackPlugin = require('html-webpack-plugin') 2 | var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({ 3 | template: __dirname + '/src/index.html', 4 | filename: 'index.html', 5 | inject: 'body' 6 | }); 7 | 8 | var config = { 9 | entry: './src/main.js', 10 | 11 | output: { 12 | path:'./dist', 13 | filename: 'index.js', 14 | }, 15 | 16 | devServer: { 17 | inline: true, 18 | port: 8888 19 | }, 20 | 21 | module: { 22 | loaders: [{test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel', query: {presets: ['es2015', 'react']}}] 23 | }, 24 | plugins: [HTMLWebpackPluginConfig] 25 | } 26 | 27 | module.exports = config; -------------------------------------------------------------------------------- /08、events/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "environment_setup", 3 | "version": "1.0.0", 4 | "description": "react enviroment set up", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --hot", 8 | "prod": "webpack -p" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "react": "^15.1.0", 15 | "react-dom": "^15.1.0", 16 | "webpack": "^1.13.1", 17 | "webpack-dev-server": "^1.14.1" 18 | }, 19 | "devDependencies": { 20 | "babel-core": "^6.10.4", 21 | "babel-loader": "^6.2.4", 22 | "babel-preset-es2015": "^6.9.0", 23 | "babel-preset-react": "^6.5.0", 24 | "html-webpack-plugin": "^2.21.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /09、ref/webpack.config.js: -------------------------------------------------------------------------------- 1 | var HtmlWebpackPlugin = require('html-webpack-plugin') 2 | var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({ 3 | template: __dirname + '/src/index.html', 4 | filename: 'index.html', 5 | inject: 'body' 6 | }); 7 | 8 | var config = { 9 | entry: './src/main.js', 10 | 11 | output: { 12 | path:'./dist', 13 | filename: 'index.js', 14 | }, 15 | 16 | devServer: { 17 | inline: true, 18 | port: 8888 19 | }, 20 | 21 | module: { 22 | loaders: [{test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel', query: {presets: ['es2015', 'react']}}] 23 | }, 24 | plugins: [HTMLWebpackPluginConfig] 25 | } 26 | 27 | module.exports = config; -------------------------------------------------------------------------------- /10、key/webpack.config.js: -------------------------------------------------------------------------------- 1 | var HtmlWebpackPlugin = require('html-webpack-plugin') 2 | var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({ 3 | template: __dirname + '/src/index.html', 4 | filename: 'index.html', 5 | inject: 'body' 6 | }); 7 | 8 | var config = { 9 | entry: './src/main.js', 10 | 11 | output: { 12 | path:'./dist', 13 | filename: 'index.js', 14 | }, 15 | 16 | devServer: { 17 | inline: true, 18 | port: 8888 19 | }, 20 | 21 | module: { 22 | loaders: [{test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel', query: {presets: ['es2015', 'react']}}] 23 | }, 24 | plugins: [HTMLWebpackPluginConfig] 25 | } 26 | 27 | module.exports = config; -------------------------------------------------------------------------------- /12、redux/webpack.config.js: -------------------------------------------------------------------------------- 1 | var HtmlWebpackPlugin = require('html-webpack-plugin') 2 | var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({ 3 | template: __dirname + '/src/index.html', 4 | filename: 'index.html', 5 | inject: 'body' 6 | }); 7 | 8 | var config = { 9 | entry: './src/main.js', 10 | 11 | output: { 12 | path:'./dist', 13 | filename: 'index.js', 14 | }, 15 | 16 | devServer: { 17 | inline: true, 18 | port: 8888 19 | }, 20 | 21 | module: { 22 | loaders: [{test: /\.js?$/, exclude: /node_modules/, loader: 'babel', query: {presets: ['es2015', 'react']}}] 23 | }, 24 | plugins: [HTMLWebpackPluginConfig] 25 | } 26 | 27 | module.exports = config; -------------------------------------------------------------------------------- /03、components/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "environment_setup", 3 | "version": "1.0.0", 4 | "description": "react enviroment set up", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --hot", 8 | "prod": "webpack -p" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "react": "^15.1.0", 15 | "react-dom": "^15.1.0", 16 | "webpack": "^1.13.1", 17 | "webpack-dev-server": "^1.14.1" 18 | }, 19 | "devDependencies": { 20 | "babel-core": "^6.10.4", 21 | "babel-loader": "^6.2.4", 22 | "babel-preset-es2015": "^6.9.0", 23 | "babel-preset-react": "^6.5.0", 24 | "html-webpack-plugin": "^2.21.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /03、components/webpack.config.js: -------------------------------------------------------------------------------- 1 | var HtmlWebpackPlugin = require('html-webpack-plugin') 2 | var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({ 3 | template: __dirname + '/src/index.html', 4 | filename: 'index.html', 5 | inject: 'body' 6 | }); 7 | 8 | var config = { 9 | entry: './src/main.js', 10 | 11 | output: { 12 | path:'./dist', 13 | filename: 'index.js', 14 | }, 15 | 16 | devServer: { 17 | inline: true, 18 | port: 8888 19 | }, 20 | 21 | module: { 22 | loaders: [{test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel', query: {presets: ['es2015', 'react']}}] 23 | }, 24 | plugins: [HTMLWebpackPluginConfig] 25 | } 26 | 27 | module.exports = config; -------------------------------------------------------------------------------- /05、componentapi/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "environment_setup", 3 | "version": "1.0.0", 4 | "description": "react enviroment set up", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --hot", 8 | "prod": "webpack -p" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "react": "^15.1.0", 15 | "react-dom": "^15.1.0", 16 | "webpack": "^1.13.1", 17 | "webpack-dev-server": "^1.14.1" 18 | }, 19 | "devDependencies": { 20 | "babel-core": "^6.10.4", 21 | "babel-loader": "^6.2.4", 22 | "babel-preset-es2015": "^6.9.0", 23 | "babel-preset-react": "^6.5.0", 24 | "html-webpack-plugin": "^2.21.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /08、events/webpack.config.js: -------------------------------------------------------------------------------- 1 | var HtmlWebpackPlugin = require('html-webpack-plugin') 2 | var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({ 3 | template: __dirname + '/src/index.html', 4 | filename: 'index.html', 5 | inject: 'body' 6 | }); 7 | 8 | var config = { 9 | entry: './src/main.js', 10 | 11 | output: { 12 | path:'./dist', 13 | filename: 'index.js', 14 | }, 15 | 16 | devServer: { 17 | inline: true, 18 | port: 8888 19 | }, 20 | 21 | module: { 22 | loaders: [{test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel', query: {presets: ['es2015', 'react']}}] 23 | }, 24 | plugins: [HTMLWebpackPluginConfig] 25 | } 26 | 27 | module.exports = config; -------------------------------------------------------------------------------- /01、environment_setup/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "environment_setup", 3 | "version": "1.0.0", 4 | "description": "react enviroment set up", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --hot", 8 | "prod": "webpack -p" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "react": "^15.1.0", 15 | "react-dom": "^15.1.0", 16 | "webpack": "^1.13.1", 17 | "webpack-dev-server": "^1.14.1" 18 | }, 19 | "devDependencies": { 20 | "babel-core": "^6.10.4", 21 | "babel-loader": "^6.2.4", 22 | "babel-preset-es2015": "^6.9.0", 23 | "babel-preset-react": "^6.5.0", 24 | "html-webpack-plugin": "^2.21.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /05、componentapi/src/jsx/FindDomNodeApp.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | class App extends React.Component { 5 | constructor() { 6 | super(); 7 | this.getDomNodeHandler = this.findDomNodeHandler.bind(this); 8 | }; 9 | 10 | findDomNodeHandler() { 11 | var myDiv = document.getElementById('myDiv'); 12 | ReactDOM.findDOMNode(myDiv).style.color = 'green'; 13 | } 14 | 15 | render() { 16 | return ( 17 | <div> 18 | <button onClick = {this.findDomNodeHandler}>FIND DOME NODE</button> 19 | <div id = "myDiv">NODE</div> 20 | </div> 21 | ); 22 | } 23 | } 24 | 25 | export default App; -------------------------------------------------------------------------------- /05、componentapi/webpack.config.js: -------------------------------------------------------------------------------- 1 | var HtmlWebpackPlugin = require('html-webpack-plugin') 2 | var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({ 3 | template: __dirname + '/src/index.html', 4 | filename: 'index.html', 5 | inject: 'body' 6 | }); 7 | 8 | var config = { 9 | entry: './src/main.js', 10 | 11 | output: { 12 | path:'./dist', 13 | filename: 'index.js', 14 | }, 15 | 16 | devServer: { 17 | inline: true, 18 | port: 8888 19 | }, 20 | 21 | module: { 22 | loaders: [{test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel', query: {presets: ['es2015', 'react']}}] 23 | }, 24 | plugins: [HTMLWebpackPluginConfig] 25 | } 26 | 27 | module.exports = config; -------------------------------------------------------------------------------- /06、lifecyclemethods/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "environment_setup", 3 | "version": "1.0.0", 4 | "description": "react enviroment set up", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --hot", 8 | "prod": "webpack -p" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "react": "^15.1.0", 15 | "react-dom": "^15.1.0", 16 | "webpack": "^1.13.1", 17 | "webpack-dev-server": "^1.14.1" 18 | }, 19 | "devDependencies": { 20 | "babel-core": "^6.10.4", 21 | "babel-loader": "^6.2.4", 22 | "babel-preset-es2015": "^6.9.0", 23 | "babel-preset-react": "^6.5.0", 24 | "html-webpack-plugin": "^2.21.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /14、betterReact/Children.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class App extends React.Component { 4 | 5 | render() { 6 | return ( 7 | <Parent> 8 | <div className="childA"></div> 9 | <div className="childB"></div> 10 | </Parent> 11 | ) 12 | } 13 | } 14 | 15 | class Parent extends React.Component { 16 | render() { 17 | console.log(this.props.children); 18 | // let items = React.Children.map(this.props.children, child => child); 19 | let items = React.Children.toArray(this.props.children); 20 | console.log(items); 21 | React.Children.forEach(this.props.children, child => console.log(child.props.className)); 22 | return null; 23 | } 24 | } 25 | 26 | export default App; 27 | -------------------------------------------------------------------------------- /01、environment_setup/webpack.config.js: -------------------------------------------------------------------------------- 1 | var HtmlWebpackPlugin = require('html-webpack-plugin') 2 | var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({ 3 | template: __dirname + '/src/index.html', 4 | filename: 'index.html', 5 | inject: 'body' 6 | }); 7 | 8 | var config = { 9 | entry: './src/main.js', 10 | 11 | output: { 12 | path:'./dist', 13 | filename: 'index.js', 14 | }, 15 | 16 | devServer: { 17 | inline: true, 18 | port: 8888 19 | }, 20 | 21 | module: { 22 | loaders: [{test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel', query: {presets: ['es2015', 'react']}}] 23 | }, 24 | plugins: [HTMLWebpackPluginConfig] 25 | } 26 | 27 | module.exports = config; -------------------------------------------------------------------------------- /06、lifecyclemethods/webpack.config.js: -------------------------------------------------------------------------------- 1 | var HtmlWebpackPlugin = require('html-webpack-plugin') 2 | var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({ 3 | template: __dirname + '/src/index.html', 4 | filename: 'index.html', 5 | inject: 'body' 6 | }); 7 | 8 | var config = { 9 | entry: './src/main.js', 10 | 11 | output: { 12 | path:'./dist', 13 | filename: 'index.js', 14 | }, 15 | 16 | devServer: { 17 | inline: true, 18 | port: 8888 19 | }, 20 | 21 | module: { 22 | loaders: [{test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel', query: {presets: ['es2015', 'react']}}] 23 | }, 24 | plugins: [HTMLWebpackPluginConfig] 25 | } 26 | 27 | module.exports = config; -------------------------------------------------------------------------------- /09、ref/src/jsx/KindsOfRefs.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class App extends React.Component { 4 | constructor(props) { 5 | super(props); 6 | this.state = { a: '' } 7 | } 8 | 9 | update() { 10 | this.setState({ 11 | a: this.refsA.value, 12 | b: this.refs.b.value 13 | }) 14 | } 15 | 16 | render() { 17 | return <div> 18 | <input 19 | ref={ node => this.refsA = node } 20 | value={this.state.a} 21 | onChange = {this.updateState.bind(this)} 22 | />{this.state.a} 23 | <hr /> 24 | <input 25 | ref="b" 26 | value={this.state.b} 27 | onChange = {this.updateState.bind(this)} 28 | />{this.state.b} 29 | </div> 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /11、router/src/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { Router, Route, Link, browserHistory, IndexRoute } from 'react-router' 4 | 5 | import App from './jsx/App.jsx'; 6 | import Home from './jsx/Home.jsx'; 7 | import About from './jsx/About.jsx'; 8 | import Contact from './jsx/Contact.jsx'; 9 | 10 | ReactDOM.render(( 11 | <Router history={browserHistory}> 12 | <Route path="/" component={App}> 13 | <IndexRoute component={Home}/> 14 | <Route path="home" component={Home}/> 15 | <Route path="about" component={About}/> 16 | <Route path="contact" component={Contact}/> 17 | </Route> 18 | </Router> 19 | 20 | ), document.getElementById('app')) -------------------------------------------------------------------------------- /11、router/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "environment_setup", 3 | "version": "1.0.0", 4 | "description": "react enviroment set up", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --hot", 8 | "prod": "webpack -p" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "react": "^15.1.0", 15 | "react-dom": "^15.1.0", 16 | "react-router": "^2.5.1", 17 | "webpack": "^1.13.1", 18 | "webpack-dev-server": "^1.14.1" 19 | }, 20 | "devDependencies": { 21 | "babel-core": "^6.10.4", 22 | "babel-loader": "^6.2.4", 23 | "babel-preset-es2015": "^6.9.0", 24 | "babel-preset-react": "^6.5.0", 25 | "html-webpack-plugin": "^2.21.0" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /04、state_props/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "environment_setup", 3 | "version": "1.0.0", 4 | "description": "react enviroment set up", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --hot", 8 | "prod": "webpack -p" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "react": "^15.1.0", 15 | "react-dom": "^15.1.0", 16 | "webpack": "^1.13.1", 17 | "webpack-dev-server": "^1.14.1" 18 | }, 19 | "devDependencies": { 20 | "babel-core": "^6.10.4", 21 | "babel-loader": "^6.2.4", 22 | "babel-preset-es2015": "^6.9.0", 23 | "babel-preset-react": "^6.5.0", 24 | "html-webpack-plugin": "^2.21.0", 25 | "json-loader": "^0.5.4" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /14、betterReact/MapApp.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class MapApp extends React.Component { 4 | 5 | constructor(props) { 6 | super(props); 7 | this.state = { 8 | items: [] 9 | } 10 | } 11 | componentWillMount() { 12 | fetch('http://xxxxx') 13 | .then(response => response.json()) 14 | .then({ results: items } => this.setState({ items })) 15 | } 16 | 17 | render() { 18 | const { items } = this.state; 19 | return ( 20 | <div> 21 | { 22 | items.map(item => 23 | <Person key={item.name} person={item} /> 24 | ) 25 | } 26 | </div> 27 | ) 28 | } 29 | } 30 | 31 | const Person = (props) => <h4>{props.person.name}</h4> 32 | 33 | export default MapApp; 34 | -------------------------------------------------------------------------------- /07、forms/src/jsx/SimpleFormApp.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class App extends React.Component { 4 | 5 | constructor(props) { 6 | super(props); 7 | 8 | this.state = { 9 | data: 'Initial data...' 10 | } 11 | this.updateState = this.updateState.bind(this); 12 | 13 | }; 14 | updateState(e) { 15 | this.setState({data: e.target.value}); 16 | } 17 | 18 | render() { 19 | return ( 20 | <div> 21 | <input type="text" value={this.state.data} placeholder="please input data..." 22 | onChange={this.updateState}/> 23 | <h4>{this.state.data}</h4> 24 | </div> 25 | ); 26 | } 27 | } 28 | 29 | export default App; -------------------------------------------------------------------------------- /11、router/webpack.config.js: -------------------------------------------------------------------------------- 1 | var HtmlWebpackPlugin = require('html-webpack-plugin') 2 | var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({ 3 | template: __dirname + '/src/index.html', 4 | filename: 'index.html', 5 | inject: 'body' 6 | }); 7 | 8 | var config = { 9 | entry: './src/main.js', 10 | 11 | output: { 12 | path:'./dist', 13 | filename: 'index.js', 14 | }, 15 | 16 | devServer: { 17 | inline: true, 18 | historyApiFallback: true, 19 | port: 8888 20 | }, 21 | 22 | module: { 23 | loaders: [{test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel', query: {presets: ['es2015', 'react']}}] 24 | }, 25 | plugins: [HTMLWebpackPluginConfig] 26 | } 27 | 28 | module.exports = config; 29 | -------------------------------------------------------------------------------- /09、ref/src/jsx/findDomNode1.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDom from 'react-dom'; 3 | 4 | class App extends React.Component { 5 | constructor(props) { 6 | super(props); 7 | this.state = { a: '' } 8 | } 9 | 10 | update() { 11 | this.setState({ 12 | a: ReactDom.findDOMNode(this.refsA).value, 13 | }) 14 | } 15 | 16 | render() { 17 | return <div> 18 | <Input 19 | ref={ component => this.refsA = component } 20 | value={this.state.a} 21 | update = {this.update.bind(this)} 22 | />{this.state.a} 23 | </div> 24 | } 25 | } 26 | const Input extends React.Component { 27 | render() { // because input is the Outermost component最外一层组件 28 | return <input onChange={this.props.update} /> 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /04、state_props/webpack.config.js: -------------------------------------------------------------------------------- 1 | var HtmlWebpackPlugin = require('html-webpack-plugin') 2 | var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({ 3 | template: __dirname + '/src/index.html', 4 | filename: 'index.html', 5 | inject: 'body' 6 | }); 7 | 8 | var config = { 9 | entry: './src/main.js', 10 | 11 | output: { 12 | path:'./dist', 13 | filename: 'index.js', 14 | }, 15 | 16 | devServer: { 17 | inline: true, 18 | port: 8888 19 | }, 20 | 21 | module: { 22 | loaders: [{test: /\.jsx?$/, 23 | exclude: /node_modules/, 24 | loader: 'babel', 25 | query: {presets: ['es2015', 'react']} 26 | }, {test: /\.json$/, loader: "json"} 27 | ] 28 | }, 29 | plugins: [HTMLWebpackPluginConfig] 30 | } 31 | 32 | module.exports = config; 33 | -------------------------------------------------------------------------------- /09、ref/src/jsx/findDomNode2.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDom from 'react-dom'; 3 | 4 | class App extends React.Component { 5 | constructor(props) { 6 | super(props); 7 | this.state = { a: '' } 8 | } 9 | 10 | update() { 11 | this.setState({ 12 | a: this.refsA.refs.input.value, 13 | }) 14 | } 15 | 16 | render() { 17 | return <div> 18 | <Input 19 | ref={ component => this.refsA = component } 20 | value={this.state.a} 21 | update = {this.update.bind(this)} 22 | />{this.state.a} 23 | </div> 24 | } 25 | } 26 | const Input extends React.Component { 27 | render() { // because input is in div, not the Outermost component非最外一层组件 28 | return <div> <input ref="input" onChange={this.props.update} /> <div> 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /05、componentapi/src/jsx/SetStateApp.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class App extends React.Component { 4 | constructor() { 5 | super(); 6 | 7 | this.state = { 8 | data: ['setState...'] 9 | } 10 | 11 | this.setStateHandler = this.setStateHandler.bind(this); 12 | }; 13 | 14 | setStateHandler() { 15 | var item = "setState..." 16 | var myArray = this.state.data; 17 | myArray.push(item) 18 | this.setState({data: myArray}) 19 | }; 20 | 21 | render() { 22 | return ( 23 | <div> 24 | <button onClick={this.setStateHandler}>SET STATE</button> 25 | <h4>State Array: {this.state.data}</h4> 26 | </div> 27 | ); 28 | } 29 | } 30 | 31 | export default App; -------------------------------------------------------------------------------- /12、redux/src/reducers/reducers.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux' 2 | import { ADD_TODO } from '../actions/actions' 3 | 4 | function todo(state, action) { 5 | switch (action.type) { 6 | 7 | case ADD_TODO: 8 | return { 9 | id: action.id, 10 | text: action.text, 11 | } 12 | 13 | default: 14 | return state 15 | } 16 | } 17 | 18 | function todos(state = [], action) { 19 | switch (action.type) { 20 | 21 | case ADD_TODO: 22 | return [ 23 | ...state, 24 | todo(undefined, action) 25 | ] 26 | 27 | default: 28 | return state 29 | } 30 | } 31 | 32 | const todoApp = combineReducers({ 33 | todos 34 | }) 35 | 36 | export default todoApp -------------------------------------------------------------------------------- /12、redux/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "environment_setup", 3 | "version": "1.0.0", 4 | "description": "react enviroment set up", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --hot", 8 | "prod": "webpack -p" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "react": "^15.1.0", 15 | "react-dom": "^15.1.0", 16 | "react-redux": "^4.4.5", 17 | "react-router": "^2.5.1", 18 | "redux": "^3.5.2", 19 | "webpack": "^1.13.1", 20 | "webpack-dev-server": "^1.14.1" 21 | }, 22 | "devDependencies": { 23 | "babel-core": "^6.10.4", 24 | "babel-loader": "^6.2.4", 25 | "babel-preset-es2015": "^6.9.0", 26 | "babel-preset-react": "^6.5.0", 27 | "html-webpack-plugin": "^2.21.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /12、redux/src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { connect } from 'react-redux' 3 | import { addTodo } from './actions/actions' 4 | 5 | import AddTodo from './components/AddTodo' 6 | import TodoList from './components/TodoList' 7 | 8 | class App extends Component { 9 | render() { 10 | const { dispatch, visibleTodos } = this.props 11 | 12 | return ( 13 | <div> 14 | 15 | <AddTodo 16 | onAddClick={text => 17 | dispatch(addTodo(text))} 18 | /> 19 | 20 | <TodoList todos={visibleTodos}/> 21 | 22 | </div> 23 | ) 24 | } 25 | } 26 | 27 | function select(state) { 28 | return { 29 | visibleTodos: state.todos 30 | } 31 | } 32 | 33 | export default connect(select)(App) -------------------------------------------------------------------------------- /13、animations/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "animations", 3 | "version": "1.0.0", 4 | "description": "react animations", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --hot", 8 | "prod": "webpack -p" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "react": "^15.1.0", 15 | "react-addons-css-transition-group": "^15.1.0", 16 | "react-dom": "^15.1.0", 17 | "webpack": "^1.13.1", 18 | "webpack-dev-server": "^1.14.1" 19 | }, 20 | "devDependencies": { 21 | "babel-core": "^6.10.4", 22 | "babel-loader": "^6.2.4", 23 | "babel-preset-es2015": "^6.9.0", 24 | "babel-preset-react": "^6.5.0", 25 | "css-loader": "^0.23.1", 26 | "html-webpack-plugin": "^2.21.0", 27 | "style-loader": "^0.13.1" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /05、componentapi/src/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | //1、for setState() 5 | //import App from './jsx/SetStateApp.jsx'; 6 | //ReactDOM.render(<App />, document.getElementById('app')) 7 | 8 | //2、for ForceUpdate 9 | //import App from './jsx/PropsApp.jsx'; 10 | //import App from './jsx/ForceUpdateApp.jsx'; 11 | //ReactDOM.render(<App />, document.getElementById('app')) 12 | 13 | //3、for Find Dom Node 14 | import App from './jsx/FindDomNodeApp.jsx'; 15 | ReactDOM.render(<App />, document.getElementById('app')); 16 | 17 | //4、state and props App 18 | //import App from './jsx/StateAndPropsApp.jsx'; 19 | //ReactDOM.render(<App />, document.getElementById('app')); 20 | 21 | //4、validating props App 22 | //import App from './jsx/ValidatingPropsApp.jsx'; 23 | //ReactDOM.render(<App />, document.getElementById('app')); -------------------------------------------------------------------------------- /03、components/src/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | //import App from './jsx/StatelessApp.jsx'; 4 | // import App from './jsx/StatefulApp.jsx'; 5 | 6 | //### 1、无状态函数式组件也支持设置默认的Props类型与值 7 | // import App from './jsx/FunctionApp.jsx'; 8 | // ReactDOM.render(<App />, document.getElementById('app')) 9 | 10 | //### 2、无状态的组件函数中,我们也是可以访问Context 11 | import Text from './jsx/FunctionApp.jsx'; 12 | class App extends React.Component { 13 | 14 | getChildContext() { 15 | return { 16 | fontFamily: 'Helvetica Neue' 17 | }; 18 | } 19 | render() { 20 | return <Text>Hello World!</Text>; 21 | } 22 | } 23 | App.childContextTypes = { 24 | fontFamily: React.PropTypes.string 25 | } 26 | 27 | 28 | // ReactDOM is part of the introduction of React 0.14 29 | ReactDOM.render( 30 | <App></App>, 31 | document.getElementById('app') 32 | ); 33 | -------------------------------------------------------------------------------- /13、animations/webpack.config.js: -------------------------------------------------------------------------------- 1 | var HtmlWebpackPlugin = require('html-webpack-plugin') 2 | var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({ 3 | template: __dirname + '/src/index.html', 4 | filename: 'index.html', 5 | inject: 'body' 6 | }); 7 | 8 | var config = { 9 | entry: './src/main.js', 10 | 11 | output: { 12 | path:'./dist', 13 | filename: 'index.js', 14 | }, 15 | 16 | devServer: { 17 | inline: true, 18 | port: 8888 19 | }, 20 | 21 | module: { 22 | loaders: [{test: /\.jsx?$/, 23 | exclude: /node_modules/, 24 | loader: 'babel', 25 | query: {presets: ['es2015', 'react']}}, 26 | { 27 | test: /\.css$/, 28 | loader: 'style!css' 29 | } 30 | ] 31 | }, 32 | plugins: [HTMLWebpackPluginConfig] 33 | } 34 | 35 | module.exports = config; 36 | -------------------------------------------------------------------------------- /09、ref/src/jsx/RefApp.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | class App extends React.Component { 5 | 6 | constructor(props) { 7 | super(props); 8 | this.state = { 9 | data: '' 10 | } 11 | this.updateState = this.updateState.bind(this); 12 | this.clearInput = this.clearInput.bind(this); 13 | }; 14 | 15 | updateState(e) { 16 | this.setState({data: e.target.value}); 17 | } 18 | 19 | clearInput() { 20 | this.setState({data: ''}); 21 | ReactDOM.findDOMNode(this.refs.myInput).focus(); 22 | } 23 | 24 | render() { 25 | return ( 26 | <div> 27 | <input value = {this.state.data} onChange = {this.updateState} 28 | ref = "myInput"></input> 29 | <button onClick = {this.clearInput}>CLEAR</button> 30 | <h4>{this.state.data}</h4> 31 | </div> 32 | ); 33 | } 34 | } 35 | 36 | export default App; 37 | -------------------------------------------------------------------------------- /04、state_props/src/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | //1、for state App 5 | //import App from './jsx/StateApp.jsx'; 6 | //ReactDOM.render(<App />, document.getElementById('app')) 7 | 8 | //2、for props App 9 | //import App from './jsx/PropsApp.jsx'; 10 | //ReactDOM.render(<App headerProp = "Header from props..." contentProp = "Content 11 | // from props..."/>, document.getElementById('app')); 12 | 13 | //3、for default props App 14 | //import App from './jsx/DefaultPropsApp.jsx'; 15 | //ReactDOM.render(<App />, document.getElementById('app')); 16 | 17 | //4、state and props App 18 | //import App from './jsx/StateAndPropsApp.jsx'; 19 | //ReactDOM.render(<App />, document.getElementById('app')); 20 | 21 | //4、validating props App 22 | // import App from './jsx/ValidatingPropsApp.jsx'; 23 | // ReactDOM.render(<App />, document.getElementById('app')); 24 | 25 | //5、综合小例子(contactsApp) 26 | import App from './jsx/ContactsApp.jsx'; 27 | ReactDOM.render(<App />, document.getElementById('app')); 28 | -------------------------------------------------------------------------------- /08、events/src/jsx/ChildEventsApp.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class App extends React.Component { 4 | 5 | constructor(props) { 6 | super(props); 7 | 8 | this.state = { 9 | data: 'Initial data...' 10 | } 11 | 12 | this.updateState = this.updateState.bind(this); 13 | }; 14 | 15 | updateState() { 16 | this.setState({data: 'Data updated from the child component...'}) 17 | } 18 | 19 | render() { 20 | return ( 21 | <div> 22 | <Content myDataProp={this.state.data} 23 | updateStateProp={this.updateState}></Content> 24 | </div> 25 | ); 26 | } 27 | } 28 | 29 | class Content extends React.Component { 30 | 31 | render() { 32 | return ( 33 | <div> 34 | <button onClick={this.props.updateStateProp}>CLICK</button> 35 | <h3>{this.props.myDataProp}</h3> 36 | </div> 37 | ); 38 | } 39 | } 40 | 41 | export default App; -------------------------------------------------------------------------------- /04、state_props/src/jsx/StateAndPropsApp.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class App extends React.Component { 4 | constructor(props) { 5 | super(props); 6 | 7 | this.state = { 8 | header: "Header from state to props...", 9 | "content": "Content from state to props..." 10 | } 11 | } 12 | 13 | render() { 14 | return ( 15 | <div> 16 | <Header headerProp = {this.state.header}/> 17 | <Content contentProp = {this.state.content}/> 18 | </div> 19 | ); 20 | } 21 | } 22 | 23 | class Header extends React.Component { 24 | render() { 25 | return ( 26 | <div> 27 | <h1>{this.props.headerProp}</h1> 28 | </div> 29 | ); 30 | } 31 | } 32 | 33 | class Content extends React.Component { 34 | render() { 35 | return ( 36 | <div> 37 | <h2>{this.props.contentProp}</h2> 38 | </div> 39 | ); 40 | } 41 | } 42 | 43 | export default App; -------------------------------------------------------------------------------- /07、forms/src/jsx/ComplexFormApp.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class App extends React.Component { 4 | 5 | constructor(props) { 6 | super(props); 7 | 8 | this.state = { 9 | data: 'Initial data...' 10 | } 11 | 12 | this.updateState = this.updateState.bind(this); 13 | }; 14 | 15 | updateState(e) { 16 | this.setState({data: e.target.value}); 17 | } 18 | 19 | render() { 20 | return ( 21 | <div> 22 | <Content myDataProp = {this.state.data} 23 | updateStateProp = {this.updateState}></Content> 24 | </div> 25 | ); 26 | } 27 | } 28 | 29 | class Content extends React.Component { 30 | 31 | render() { 32 | return ( 33 | <div> 34 | <input type = "text" value = {this.props.myDataProp} 35 | onChange = {this.props.updateStateProp} /> 36 | <h3>{this.props.myDataProp}</h3> 37 | </div> 38 | ); 39 | } 40 | } 41 | export default App; -------------------------------------------------------------------------------- /04、state_props/README.md: -------------------------------------------------------------------------------- 1 | ## 启动步骤 2 | * 1、npm install 3 | * 2、npm start,然后可以在浏览器中打开localhost:8888 <br/> 4 | 或者npm run prod,然后可以到dist目录下打开index.html <br/> 5 | 或者直接webpack,然后可以到dist目录下打开index.html 6 | 7 | ## React Components组件介绍 8 | 9 | ### 状态组件(state components) 10 | state状态,仅和自身有关,不受父组件控制 11 | 12 | ### 属性组件(props components) 13 | 由父组件传给子组件属性值 14 | 15 | ### 默认属性(Default Props) 16 | 在组件中可以设置默认的属性值 17 | 18 | ### state和props混合 19 | 组件state状态值当成props属性值传给子组件 20 | 21 | ### 验证属性(Validating props) 22 | 在`App.propTypes`中对属性类型验证,当属性使用中类型不是指定的类型会在`console`控制台上报`warning`提醒, <br /> 23 | 在`App.propTypes`指定属性类型后,可以设置`App.defaultProps`给属性默认值 <br /> 24 | 25 | 1、对于指定`isRequired`的属性,当未设置该属性值的话,控制台会报 26 | ``` 27 | "Warning: Failed propType: Required prop `propBool` was not specified in `App`." 28 | ``` 29 | 2、当出现和设置的属性值类型不一致的情况,控制台会报 30 | ``` 31 | “Warning: Failed propType: Invalid prop `propNumber` of type `string` supplied to `App`, expected `number`.” 32 | ``` 33 | ### 自定义验证属性(custom Validating props) 34 | * 1、属性缺失 35 | * 2、属性值长度不够 36 | 37 | ### 综合小例子(contactsApp) 38 | [参考链接](https://github.com/pro-react/sample-code/tree/master/chapter%203/contactsApp) 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 theScoreONE 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /03、components/README.md: -------------------------------------------------------------------------------- 1 | ## 启动步骤 2 | * 1、npm install 3 | * 2、npm start,然后可以在浏览器中打开localhost:8888. 4 | 5 | 或者npm run prod,然后可以到dist目录下打开index.html. 6 | 7 | 或者直接webpack,然后可以到dist目录下打开index.html 8 | 9 | ## React Components组件介绍 10 | 11 | ### 无状态组件(Stateless Components) 12 | 参考**StatelessApp.jsx** <br/>. 13 | 然后将StatelessApp.jsx引入(import)到main.js文件并调用reactDOM.render(). 14 | 15 | **顾名思义, 无state状态的组件** 16 | 17 | ### 状态组件(Stateful Components) 18 | 19 | 【注意】给组件`key`属性,当改变代码后,帮助`React`仅更新渲染更改部分而不是全部重新渲染,这对性能有很大的提升 20 | 21 | ### 函数声明组件(Function Components) 22 | 23 | 函数式组件与基于`Class`声明的组件相比,其具有以下特性: 24 | 25 | * 不需要声明类,可以避免大量的譬如`extends`或者`constructor`这样的代码 26 | * 不需要显示声明`this`关键字,在ES6的类声明中往往需要将函数的`this`关键字绑定到当前作用域,而因为函数式声明的特性,我们不需要再强制绑定: 27 | ```javascript 28 | onClick={this.sayHi.bind(this)}>Say Hi</a> 29 | onClick={sayHi}>Say Hi</a> 30 | ``` 31 | * 贯彻最佳实践,在`React`组件复用与组合中我们会提到,应当避免在底层的展示性组件中混入对于状态的管理,而应该将状态托管于某个高阶组件或者其他的状态容器中。利用函数式声明组件可以彻底保证不会在组件中进行状态操作。 32 | * 易于理解与测试 33 | * 更佳的性能表现:因为函数式组件中并不需要进行生命周期的管理与状态管理,因此`React`并不需要进行某些特定的检查或者内存分配,从而保证了更好地性能表现。 34 | 35 | #### 高阶组件(Higher-Order Components) 36 | * 查看`HocApp.jsx` 37 | 38 | #### 可重用组件(ReUseable Components) 39 | 应用到refs 40 | -------------------------------------------------------------------------------- /00、es6-notes/04-Object对象.md: -------------------------------------------------------------------------------- 1 | * 一、ECMAScript 6新标记 2 | * 二、把对象的值复制一份到另一个对象(Object.assign()) 3 | 4 | #### 一、ECMAScript 6新标记 5 | [《Object initializer》](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Object_initializer) 6 | 7 | * 1、属性的简写 8 | * 2、方法的简写,"function" 关键字也可以丢掉 9 | * 3、计算的属性名 10 | ```javascript 11 | // 1、Shorthand property names (ES6) 12 | var a = "foo", b = 42, c = {}; 13 | var o = { a, b, c }; 14 | 15 | // 2、Shorthand method names (ES6) 16 | var o = { 17 | property([parameters]) {}, 18 | get property() {}, 19 | set property(value) {}, 20 | * generator() {} 21 | }; 22 | /* 生成器ES5和ES6对比 23 | 1、//EC6提供了一种简明地定义以生成器函数作为值的属性的方法 24 | var o = { 25 | * generator() { 26 | ........... 27 | } 28 | }; 29 | 2、ECMAScript 5 中可以这样书写 (需要注意的时 ES5 没有生成器): 30 | var o = { 31 | generatorMethod: function *() { 32 | ........... 33 | } 34 | }; 35 | */ 36 | 37 | // 3、Computed property names (ES6) 38 | var prop = "foo"; 39 | var o = { 40 | [prop]: "hey", 41 | ["b" + "ar"]: "there", 42 | }; 43 | ``` 44 | 45 | #### 七、把对象的值复制一份到另一个对象(Object.assign()) 46 | ```javascript 47 | let num1 = {one: 1}; 48 | let num2 = Object.assign({}, num1, {two: 2}); 49 | console.log(num1);//{one: 1} 50 | console.log(num2);//{one: 1, two: 2} 51 | ``` 52 | -------------------------------------------------------------------------------- /10、key/src/jsx/KeyApp.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class App extends React.Component { 4 | constructor() { 5 | super(); 6 | this.state = { 7 | data: [ 8 | { 9 | component: 'First...', 10 | id: 1 11 | }, 12 | { 13 | component: 'Second...', 14 | id: 2 15 | }, 16 | { 17 | component: 'Third...', 18 | id: 3 19 | } 20 | ] 21 | } 22 | 23 | } 24 | 25 | render() { 26 | return ( 27 | <div> 28 | <div> 29 | {this.state.data.map((dynamicComponent, i) => <Content 30 | key={i} componentData={dynamicComponent}/>)} 31 | </div> 32 | </div> 33 | ); 34 | } 35 | } 36 | 37 | class Content extends React.Component { 38 | render() { 39 | return ( 40 | <div> 41 | <div>{this.props.componentData.component}</div> 42 | <div>{this.props.componentData.id}</div> 43 | </div> 44 | ); 45 | } 46 | } 47 | 48 | export default App; -------------------------------------------------------------------------------- /13、animations/src/styles/style.css: -------------------------------------------------------------------------------- 1 | /*bacause " transitionName = "example" "*/ 2 | /* 3 | .example-appear { 4 | opacity: 0.01; 5 | } 6 | 7 | .example-appear.example-appear-active { 8 | opacity: 1; 9 | transition: opacity 800ms ease-in; 10 | } 11 | 12 | .example-enter { 13 | opacity: 0.01; 14 | } 15 | 16 | .example-enter.example-enter-active { 17 | opacity: 1; 18 | transition: opacity 500ms ease-in; 19 | } 20 | 21 | .example-leave { 22 | opacity: 1; 23 | } 24 | 25 | .example-leave.example-leave-active { 26 | opacity: 0.01; 27 | transition: opacity 500ms ease-in; 28 | } 29 | */ 30 | .example-enter { 31 | opacity: 0; 32 | transform: translateX(-250px); 33 | } 34 | .example-enter.example-enter-active { 35 | opacity: 1; 36 | transform: translateX(0); 37 | transition: 0.3s; 38 | } 39 | 40 | 41 | .example-leave { 42 | opacity: 1; 43 | transform: translateX(0); 44 | } 45 | 46 | .example-leave.example-leave-active { 47 | opacity: 0; 48 | transform: translateX(250px); 49 | transition: 0.3s; 50 | } 51 | 52 | .example-appear { 53 | opacity: 0; 54 | transform: translateX(-250px); 55 | } 56 | .example-appear.example-appear-active { 57 | opacity: 1; 58 | transform: translateX(0); 59 | transition: .3s; 60 | } 61 | -------------------------------------------------------------------------------- /00、es6-notes/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## 01-变量和参数 3 | 4 | * 一、const、let与原var 5 | * 二、对象和数组解构(Destructuring) 6 | * 三、参数默认值 7 | * 四、Spread展开 / Rest剩余 操作符 8 | * 五、模板语法和分隔符 9 | 10 | ## 02-class类 11 | 12 | * 一、Classes类 13 | * 二、Getters和Setters 14 | * 三、继承(Inheritance) 15 | 16 | ## 03-FunctionalJS函数 17 | 18 | * 一、箭头函数=> 19 | * 二、箭头作为异步callback 20 | * 三、迭代器(Iterators) 21 | * 四、生成器(Generators) 22 | 23 | 24 | ## 04-Object对象 25 | 26 | * 一、ECMAScript 6新标记 27 | * 二、把对象的值复制一份到另一个对象(Object.assign()) 28 | 29 | ## 05-array、map、set 30 | * 一、Arrays 31 | * 二、Set 和 WeakSet 32 | * 三、Map 和 WeakMap 33 | * 四、Symbols 34 | 35 | ## 06-Promise 36 | 37 | * 一、Promise 38 | * 二、Promise基础 39 | * 三、Promise的API 40 | * 四、Promise实战 41 | 42 | ## 07-Modules模块化 43 | 44 | * 一、IIFE 45 | * 二、CommonJS 模块化 46 | * 三、AMD 47 | * 四、ES6模块化 48 | 49 | 50 | ## 参考链接 51 | 52 | * [ES6基础](http://blog.csdn.net/mqy1023/article/details/51814629) 53 | * [es6_learning_notes](https://github.com/tayiorbeii/es6_learning_notes) 54 | * [ECMAScript6扫盲](http://www.cnblogs.com/hustskyking/archive/2016/07/11/5659835.html) 55 | * [es6-cheatsheet](https://github.com/DrkSephy/es6-cheatsheet) 56 | * [ES6 In Depth](https://hacks.mozilla.org/page/2/?s=ES6+In+Depth) 57 | * [ES6 In Depth中文翻译版](http://bubkoo.com/2015/06/14/es6-in-depth-an-introduction/) 58 | -------------------------------------------------------------------------------- /03、components/src/jsx/HocApp.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const HOC = (InnerComponent) => class extends React.Component { 4 | 5 | constructor() { 6 | super(); 7 | this.state = { count: 0 }; 8 | } 9 | componentWillMount() { 10 | console.log('componentWillMount'); 11 | } 12 | update() { 13 | this.setState({ count: this.state.count + 1 }); 14 | } 15 | render() { 16 | return ( 17 | <InnerComponent 18 | {...this.props} 19 | {...this.state} 20 | update={this.update.bind(this)} 21 | /> 22 | ) 23 | } 24 | } 25 | 26 | class App extends React.Component { 27 | render() { 28 | return ( 29 | <div> 30 | <Button>button</Button> 31 | <hr /> 32 | <LabelHOC>label</LabelHOC> 33 | </div> 34 | ) 35 | } 36 | } 37 | 38 | // 点击 + 1 39 | const Button = HOC((props) => 40 | <button onClick={props.update}>{props.children} - {props.count}</button> 41 | ) 42 | 43 | // 划过 + 1 44 | class Label extends React.Component { 45 | componentWillMount() { 46 | console.log('Label componentWillMount'); 47 | } 48 | render() { 49 | return ( 50 | <label onMouseOver={this.props.update}>{this.props.children} - {this.props.count}</label> 51 | ) 52 | } 53 | } 54 | const LabelHOC = HOC(Label); 55 | 56 | export default App; 57 | -------------------------------------------------------------------------------- /03、components/src/jsx/ReUseableApp.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | // import Buttons from './cloneElement/Buttons'; 3 | import ReactDom from 'react-dom'; 4 | 5 | class App extends React.Component { 6 | 7 | constructor() { 8 | super(); 9 | this.state = { 10 | red: 0, 11 | green: 128, 12 | blue: 255 13 | } 14 | this.update = this.update.bind(this); 15 | } 16 | 17 | update(e) { 18 | this.setState({ 19 | red: ReactDom.findDOMNode(this.refs.red.refs.inp).value, 20 | green: ReactDom.findDOMNode(this.refs.green.refs.inp).value, 21 | blue: ReactDom.findDOMNode(this.refs.blue.refs.inp).value, 22 | }) 23 | } 24 | 25 | render() { 26 | return ( 27 | <div> 28 | <Slider ref="red" update={this.update} value={this.state.red} />{this.state.red}<br /> 29 | <Slider ref="green" update={this.update} value={this.state.green} />{this.state.green}<br /> 30 | <Slider ref="blue" update={this.update} value={this.state.blue} />{this.state.blue}<br /> 31 | </div> 32 | ) 33 | } 34 | } 35 | 36 | class Slider extends React.Component { 37 | render() { 38 | return ( 39 | <div> 40 | <input ref="inp" type="range" 41 | min="0" 42 | max="255" 43 | value={this.props.value} 44 | onChange={this.props.update} 45 | /> 46 | </div> 47 | ) 48 | } 49 | } 50 | 51 | export default App; 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # learn react with es6 2 | 3 | ### 0、[ES6语法基础](./00-es6-notes) 4 | 5 | * 变量和参数 6 | * class类 7 | * Function函数 8 | * Object对象 9 | * Promise 10 | * Modules模块化 11 | 12 | ### 1、[搭建React开发环境](./environment_setup) 13 | 14 | * react开发环境搭建 15 | 16 | ### 2、[JSX语法](./jsx) 17 | 18 | * 内嵌元素(Nested Elements) 19 | * 添加属性(Attributes) 20 | * Js表达式(JavaScript Expressions) 21 | * 样式(Styling) 22 | * 注释(Comments) 23 | * 命名约定(Naming Convention) 24 | 25 | ### 3、[Components组件](./components) 26 | 27 | * 无状态组件(Stateless Components) 28 | * 状态组件(Stateful Components) 29 | * 函数式声明组件(Function Components) 30 | * 可重用组件 31 | 32 | ### 4、[state状态和props属性](./state_props) 33 | 34 | * 状态组件(state components) 35 | * 属性组件(props components) 36 | * 默认属性(Default Props) 37 | * state和props混合 38 | * 验证属性(Validating props) 39 | * 自定义属性验证 40 | * **综合小例子(contactsApp)** 41 | 42 | ### 5、[Components组件的API](./componentapi) 43 | 44 | * 设置状态setState() 45 | * 强制更新ForceUpdate 46 | * 查找DOM节点Find Dom Node 47 | 48 | ### 6、[Components组件生命周期](./lifecyclemethods) 49 | 50 | ### 7、[Forms表单](./forms) 51 | 52 | ### 8、[Event事件](./events) 53 | 54 | ### 9、[ref元素引用](./ref) 55 | 56 | ### 10、[key键属性](./key) 57 | 58 | ### 11、[router路由](./router) 59 | 60 | ### 12、[redux架构](./redux) 61 | 62 | ### 13、[Animations动画](./animations) 63 | 64 | * ** 65 | 66 | * [ES6入门](https://github.com/joemaddalone/egghead-react-fundamentals-es6/tree/master/lessons) 67 | 68 | * [react入门](https://egghead.io/courses/react-fundamentals) 69 | -------------------------------------------------------------------------------- /04、state_props/src/jsx/ValidatingPropsApp.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class App extends React.Component { 4 | render() { 5 | return ( 6 | <div> 7 | <h3>Array: {this.props.propArray}</h3> 8 | <h3>Bool: {this.props.propBool ? "True..." : "False..."}</h3> 9 | <h3>Func: {this.props.propFunc(3)}</h3> 10 | <h3>Number: {this.props.propNumber}</h3> 11 | <h3>String: {this.props.propString}</h3> 12 | <h3>Object: {this.props.propObject.objectName1}</h3> 13 | <h3>Object: {this.props.propObject.objectName2}</h3> 14 | <h3>Object: {this.props.propObject.objectName3}</h3> 15 | </div> 16 | ); 17 | } 18 | } 19 | 20 | App.propTypes = { 21 | propArray: React.PropTypes.array.isRequired, 22 | propBool: React.PropTypes.bool.isRequired, 23 | propFunc: React.PropTypes.func, 24 | propNumber: React.PropTypes.number, 25 | propString: React.PropTypes.string, 26 | propObject: React.PropTypes.object 27 | } 28 | 29 | App.defaultProps = { 30 | propArray: [1, 2, 3, 4, 5], 31 | propBool: true, 32 | propFunc: function (e) { 33 | return e * e 34 | }, 35 | propNumber: 1, 36 | propString: "String value...", 37 | 38 | propObject: { 39 | objectName1: "objectValue1", 40 | objectName2: "objectValue2", 41 | objectName3: "objectValue3" 42 | } 43 | } 44 | 45 | export default App; -------------------------------------------------------------------------------- /06、lifecyclemethods/src/jsx/App.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class App extends React.Component { 4 | 5 | constructor(props) { 6 | super(props); 7 | 8 | this.state = { 9 | data: 0 10 | } 11 | 12 | this.setNewNumber = this.setNewNumber.bind(this) 13 | } 14 | 15 | setNewNumber() { 16 | this.setState({data: this.state.data + 1}) 17 | } 18 | 19 | render() { 20 | return ( 21 | <div> 22 | <button onClick={this.setNewNumber}>INCREMENT</button> 23 | <Content myNumber={this.state.data}></Content> 24 | </div> 25 | ); 26 | } 27 | } 28 | 29 | class Content extends React.Component { 30 | 31 | componentWillMount() { 32 | console.log('Component WILL MOUNT!') 33 | } 34 | 35 | componentDidMount() { 36 | console.log('Component DID MOUNT!') 37 | } 38 | 39 | componentWillReceiveProps(newProps) { 40 | console.log('Component WILL RECIEVE PROPS!') 41 | } 42 | 43 | shouldComponentUpdate(newProps, newState) { 44 | return true; 45 | } 46 | 47 | componentWillUpdate(nextProps, nextState) { 48 | console.log('Component WILL UPDATE!'); 49 | } 50 | 51 | componentDidUpdate(prevProps, prevState) { 52 | console.log('Component DID UPDATE!') 53 | } 54 | 55 | componentWillUnmount() { 56 | console.log('Component WILL UNMOUNT!') 57 | } 58 | 59 | render() { 60 | return ( 61 | <div> 62 | <h3>{this.props.myNumber}</h3> 63 | </div> 64 | ); 65 | } 66 | } 67 | 68 | export default App; 69 | -------------------------------------------------------------------------------- /03、components/src/jsx/StatefulApp.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | //Parent Component 4 | class App extends React.Component { 5 | constructor() { 6 | super(); 7 | 8 | this.state = { 9 | data: [ 10 | { 11 | "id": 1, 12 | "name": "Foo", 13 | "age": "20" 14 | }, 15 | 16 | { 17 | "id": 2, 18 | "name": "Bar", 19 | "age": "30" 20 | }, 21 | 22 | { 23 | "id": 3, 24 | "name": "Baz", 25 | "age": "40" 26 | } 27 | ] 28 | } 29 | } 30 | 31 | render() { 32 | return ( 33 | <div> 34 | <Header/> 35 | <table> 36 | <tbody> 37 | {this.state.data.map((person, i) => <TableRow key = {i} data = {person} />)} 38 | </tbody> 39 | </table> 40 | </div> 41 | ); 42 | } 43 | } 44 | //Header Child Component 45 | class Header extends React.Component { 46 | render() { 47 | return ( 48 | <div> 49 | <h1>Header</h1> 50 | </div> 51 | ); 52 | } 53 | } 54 | //TableRow Child Component 55 | class TableRow extends React.Component { 56 | render() { 57 | return ( 58 | <tr> 59 | <td>{this.props.data.id}</td> 60 | <td>{this.props.data.name}</td> 61 | <td>{this.props.data.age}</td> 62 | </tr> 63 | ); 64 | } 65 | } 66 | 67 | export default App; 68 | -------------------------------------------------------------------------------- /13、animations/src/jsx/AnimationApp.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | var ReactCSSTransitionGroup = require('react-addons-css-transition-group'); 3 | 4 | class App extends React.Component { 5 | 6 | constructor(props) { 7 | super(props); 8 | 9 | this.state = { 10 | items: ['Item 1...', 'Item 2...', 'Item 3...', 'Item 4...'] 11 | } 12 | 13 | this.handleAdd = this.handleAdd.bind(this); 14 | }; 15 | 16 | handleAdd() { 17 | var newItems = this.state.items.concat([prompt('Create New Item')]); 18 | this.setState({items: newItems}); 19 | } 20 | 21 | handleRemove(i) { 22 | var newItems = this.state.items.slice(); 23 | newItems.splice(i, 1); 24 | this.setState({items: newItems}); 25 | } 26 | 27 | render() { 28 | var items = this.state.items.map(function (item, i) { 29 | return ( 30 | <div key={item} onClick={this.handleRemove.bind(this, i)}> 31 | {item} 32 | </div> 33 | ); 34 | 35 | }.bind(this)); 36 | 37 | return ( 38 | <div> 39 | <button onClick={this.handleAdd}>Add Item</button> 40 | 41 | <ReactCSSTransitionGroup transitionName="example" 42 | transitionEnterTimeout={500} 43 | transitionLeaveTimeout={500} 44 | transitionAppear={true} 45 | transitionAppearTimeout={300}> 46 | {items} 47 | </ReactCSSTransitionGroup> 48 | </div> 49 | ); 50 | } 51 | } 52 | 53 | export default App; 54 | -------------------------------------------------------------------------------- /01、environment_setup/README.md: -------------------------------------------------------------------------------- 1 | ## 搭建步骤 2 | 准备:本机必须先安装nodejs环境,可命令行键入:node -v //查看是否安装&node版本信息 3 | ### step1— — 安装全局包 4 | ```bash 5 | 如:webpack 6 | window下需“以管理者身份运行cmd”,然后: npm install -g webpack 7 | ``` 8 | ### step2:创建react项目并初始化package.json管理包 9 | * mkdir reactApp 10 | * npm init --yes 11 | ### step3: 添加依赖和插件 12 | ```bash 13 | //1、webpack构建项目 14 | npm install webpack --save 15 | npm install webpack-dev-server --save 16 | //2、react核心库 17 | npm install react --save 18 | npm install react-dom --save 19 | //3、babel转译es6 20 | npm install babel-core --save-dev 21 | npm install babel-loader --save-dev 22 | npm install babel-preset-react --save-dev 23 | npm install babel-preset-es2015 --save-dev 24 | //4、转译后输出的xxx.js插入inject到index.html中的插件 25 | npm install html-webpack-plugin --save-dev 26 | ``` 27 | ### step4:创建项目文件,es6语法的jsx和构建包配置webpack.config.js 28 | 项目目录结构为: 29 | ``` 30 | . 31 | ├── src 32 | ├── jsx 33 | ├── App.jsx 34 | ├── main.js 35 | ├── index.html 36 | ├── package.json 37 | ├── README.md 38 | ├── webpack.cofig.js 39 | ``` 40 | ### step5:设置Compiler、 Server和Loaders 41 | ```bash 42 | 1、webpack.config.js文件中构建配置 43 | a、entry,入口文件main.js 44 | b、output,指定输出后的index.js 45 | c、devServer,设置服务器端口 46 | d、babel,loader使用es2015和react presets 47 | e、html-webpack-plugin插件,让转译后的index.js插入inject到index.html的body下,并复制indx.html到输出的dist目录 48 | 2、修改package.json中的"script" 49 | a、"start": "webpack-dev-server --hot" 50 | 命令行:npm start可以启动服务器,其中“--hot”命令是当修改源码后不用重新刷新浏览器,也能实时重新加载到最新源码 51 | b、"prod": "webpack -p" 52 | 命令行:npm run prod可以输出生产情况下的构建包,可以看到生成dist目录并有index.html和index.js 53 | ``` 54 | ### step6:编写index.html和App.jsx还有入口的main.js 55 | 56 | ### step7:启动服务器 57 | 编写npm script 58 | ``` 59 | npm start,然后可以在浏览器中打开localhost:8888 60 | 或者npm run prod,然后可以到dist目录下打开index.html 61 | ``` 62 | **==> 能在浏览器中看到“Hello World!!!”,说明React开发环境搭建成功了!!** 63 | 64 | * **后续React开发均在本次的搭建React环境基础上** 65 | -------------------------------------------------------------------------------- /00、es6-notes/02-class类.md: -------------------------------------------------------------------------------- 1 | 2 | * 一、Classes类 3 | * 二、Getters和Setters 4 | * 三、继承(Inheritance) 5 | 6 | #### 一、Classes类 <br /> 7 | ES6中的class类是基于Javascript原有的原型(prototype)继承(inheritance),<br /> 8 | class并不是新的一种面向对象js模型,而是提供了更简单、更清晰创建对象和处理继承关系的语法【typeof Employee; //'function'】<br /> 9 | 1、老方法编写一个类 <br /> 10 | ```javascript 11 | var Employee = function() { }; 12 | Employee.prototype = { //prototype 13 | doSomething: function(){ 14 | return "done!"; 15 | } 16 | }; 17 | var e = new Employee(); 18 | ``` 19 | 2、ES6编写类 20 | ```javascript 21 | class Employee { 22 | doSomething() { 23 | return "complete!"; 24 | } 25 | doSomethingElse() { 26 | return "also complete!" 27 | } 28 | } 29 | typeof Employee; // 'function' 30 | var e = new Employee(); 31 | e.doSomething(); // "complete!" 32 | ``` 33 | 3、Constructor构造器 34 | ```javascript 35 | class Employee { 36 | constructor(name) { 37 | this._name = name; 38 | } 39 | doSomething() { 40 | return "complete!"; 41 | } 42 | getName() { 43 | return this._name; 44 | } 45 | } 46 | 47 | let e1 = new Employee("Taylor"); 48 | let e2 = new Employee("Charles"); 49 | 50 | e1.getName(); // "Taylor" 51 | e2.getName(); // "Charles" 52 | ``` 53 | #### 二、Getters和Setters 54 | ```javascript 55 | class Person { 56 | constructor(name) { 57 | this.name = name; 58 | } 59 | get name() { 60 | return this._name; 61 | } 62 | set name(newValue) { 63 | this._name = newValue; 64 | } 65 | } 66 | let e1 = new Person("Taylor"); 67 | console.log(e1.name); // "Taylor" 68 | ``` 69 | #### 三、继承(Inheritance) 70 | extends继承、super父类、 71 | ```javascript 72 | //在Getters和Setters的代码基础上 73 | class Employee extends Person { 74 | constructor(title, name) { 75 | super(name); 76 | this._title = title; 77 | } 78 | doWork() { 79 | return `${this._name} is working`; // uses ES6's literal syntax 80 | } 81 | } 82 | 83 | let p1 = new Person("Taylor"); 84 | let e1 = new Employee("Chris"); 85 | e1.doWork(); // "Chris is working" 86 | ``` 87 | -------------------------------------------------------------------------------- /06、lifecyclemethods/README.md: -------------------------------------------------------------------------------- 1 | ## 启动步骤 2 | * 1、npm install 3 | * 2、npm start, 然后可以在浏览器中打开localhost:8888. 4 | 或者npm run prod,然后可以到dist目录下打开index.html.看package.json中对应的该命令 5 | 6 | ## React Components组件生命周期 7 | 8 | #### 一、初始化及挂载阶段 9 | * 1、这是组件类的构造函数,通常在此初始化state数据模型。 10 | ```javascript 11 | constructor(props) { 12 | super(props); 13 | this.state = { 14 | //key : value 15 | }; 16 | } 17 | ``` 18 | * 2、componentWillMount在rendering渲染前执行,在服务端和客户端都会被执行 19 | ```javascript 20 | componentWillMount() { 21 | 22 | } 23 | ``` 24 | * 3、componentDidMount在客户端第一次render渲染后被执行,通知组件已经加载完成,虚拟DOM已构建完成, 25 | 可以在该函数中Ajax请求、修改DOM、setTimeout或setInterval,还可更新state触发组件中其他生命周期方法. 26 | ```javascript 27 | componentDidMount() { 28 | this.props.fetchAirports(); 29 | } 30 | ``` 31 | #### 二、运行期阶段 32 | * 1、componentWillReceiveProps, 通常在此方法接收新的props值,重新设置state. 33 | ```javascript 34 | componentWillReceiveProps(nextProps) { 35 | this.setState({ 36 | //key : value 37 | }); 38 | } 39 | ``` 40 | * 2、shouldComponentUpdate:接受新props或state时调用; 如果该方法返回false,则componentWillUpdate(nextProps, nextState)及其之后执行的方法都不会执行,组件则不会进行重新渲染。 41 | ```javascript 42 | shouldComponentUpdate(nextProps, nextState) { 43 | // return nextProps.val % 5 === 0; 44 | return nextProps.id !== this.props.id; 45 | } 46 | ``` 47 | * 3、componentWillUpdate,在shouldComponentUpdate返回true后立刻调用,rendering渲染方法前被调用 48 | ```javascript 49 | componentWillUpdate(nextProps, nextState){ 50 | let originAndDestinationSelected = nextProps.origin && nextProps.destination; 51 | let selectionHasChangedSinceLastUpdate = nextProps.origin !== this.props.origin || 52 | nextProps.destination !== this.props.destination; 53 | if(originAndDestinationSelected && selectionHasChangedSinceLastUpdate){ 54 | this.props.fetchTickets(nextProps.origin, nextProps.destination); 55 | } 56 | } 57 | ``` 58 | * 4、componentDidUpdate,在render()渲染方法后被调用 59 | ``` 60 | componentDidUpdate(preProps, preState) { 61 | console.log(`preProps: ${preProps.val}`); // 打印后面的render的前一个值 62 | } 63 | ``` 64 | * **5、render方法用于渲染组件。在初始化阶段和运行期阶段都会执行** 65 | ```javascript 66 | render() { 67 | return( 68 | <View/> 69 | ); 70 | } 71 | ``` 72 | ### 三、卸载阶段 73 | * 1、componentWillUnmount,组件从DOM节点中被卸载unmounted时被调用,一般用于clearInterval等 74 | ```javascript 75 | componentWillUnmount() { 76 | 77 | } 78 | ``` 79 | 80 | ## 组件生命周期例子分析 81 | ![组件生命周期](../images/lifecycle.png) 82 | 83 | * 1、组件渲染成功,会调用componentWillMount和componentDidMount 84 | 85 | * 2、每点击一次**INCREMENT**按钮,更改props属性值,都会调用以下三个方法打印出: 86 | ```bash 87 | Component WILL RECIEVE PROPS! 88 | Component WILL UPDATE! 89 | Component DID UPDATE! 90 | ``` 91 | * 3、十秒后卸载组件,调用unmout打印出: 92 | ```bash 93 | Component WILL UNMOUNT! 94 | ``` 95 | 96 | ## 更多链接 97 | [React入门笔记(二) — 组件的生命周期](http://blog.csdn.net/mqy1023/article/details/51571320) 98 | -------------------------------------------------------------------------------- /00、es6-notes/07-Modules模块化.md: -------------------------------------------------------------------------------- 1 | * 一、IIFE 2 | * 二、CommonJS 模块化 3 | * 三、AMD 4 | * 四、ES6模块化 5 | 6 | #### 一、立即自执行函数表达式immediately invoked function expression (IIFE) 7 | 1、通过target.Employee = Employee将其绑定给浏览器窗口, 全局暴露 8 | 2、privateDoWork只在IIFE的closure中可见 9 | ```javascript 10 | (function(target) { 11 | var privateDoWork = function(name) { 12 | return name + " is working"; 13 | }; 14 | 15 | var Employee = function(name) { 16 | this.name = name; 17 | } 18 | 19 | Employee.prototype = { 20 | doWork: function() { 21 | return privateDoWork(this.name); 22 | } 23 | } 24 | 25 | target.Employee = Employee; 26 | }(window)); 27 | ``` 28 | #### 二、CommonJS 29 | exports 和 require. 30 | ```javascript 31 | var privateDoWork = function(name) { 32 | return name + " is working"; 33 | } 34 | 35 | var Employee = function(name) { 36 | this.name = name; 37 | } 38 | 39 | Employee.prototype = { 40 | doWork: function() { 41 | return privateDoWork(this.name); 42 | } 43 | } 44 | 45 | exports.Employee = Employee; 46 | ``` 47 | ```javascript 48 | var Employee = require('./Employee').Employee; 49 | 50 | var e1 = new Employee("Taylor"); 51 | console.log(e1.doWork()); // "Taylor is working" 52 | ``` 53 | #### 三、AMD 54 | ```javascript 55 | // employee.js 56 | define(function() { 57 | var privateDoWork = function() { 58 | // ... 59 | } 60 | var Employee = function(name) { 61 | // ... 62 | } 63 | return Employee; 64 | }); 65 | ``` 66 | ```javascript 67 | define(["employee"], function(Employee){ 68 | var e = new Employee("Taylor"); 69 | }); 70 | ``` 71 | #### 四、ES6 72 | 一个ES6模块(module)是一个包含js代码的文件 <br /> 73 | 1、Export <br /> 74 | 可以export出函数、class、var、let、const 75 | ```javascript 76 | //utility.js, 暴露一个对象列表 77 | function generateRandom() { 78 | return Math.random(); 79 | } 80 | function sum(a, b) { 81 | return a + b; 82 | } 83 | export { generateRandom, sum } 84 | ``` 85 | 2、Default Exports 86 | ```javascript 87 | var utils = { 88 | generateRandom() { 89 | return Math.random(); 90 | }, 91 | sum(a, b) { 92 | return a + b; 93 | } 94 | }; 95 | export default utils; 96 | ``` 97 | 3、Import 98 | ```javascript 99 | import { generateRandom, sum } from 'utility'; 100 | console.log(generateRandom()); //logs a random number 101 | console.log(sum(1, 2)); //3 102 | 103 | //import default导入默认,不需要{ } 104 | //import utils from 'utility'; 105 | //console.log(utils.generateRandom()); //logs a random number //console.log(utils.sum(1, 2)); //3 106 | ``` 107 | 4、重命名导入: 108 | ```javascript 109 | import { 110 | sumTwo as addTwoNumbers, 111 | sumThree as sumThreeNumbers 112 | } from 'math/addition'; 113 | ``` 114 | 5、导入所有的东西(整体加载): 115 | ```javascript 116 | import * as util from 'math/addition'; 117 | 118 | //可以从一个模块中导入一个值的列表: 119 | import * as additionUtil from 'math/addition'; 120 | const { sumTwo, sumThree } = additionUtil; 121 | ``` 122 | 6、混合默认default的导入和混合导入 123 | ```javascript 124 | import defaultFoo, { foo1, foo2 } from 'foos'; 125 | 126 | //react的导入 127 | import React, { Component, PropTypes } from 'react'; 128 | ``` 129 | -------------------------------------------------------------------------------- /02、jsx/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## 启动步骤 3 | * 1、npm install 4 | * 2、npm start,然后可以在浏览器中打开localhost:8888 5 | 或者npm run prod,然后可以到dist目录下打开index.html <br/> 6 | 或者直接webpack,然后可以到dist目录下打开index.html 7 | 8 | ## JSX介绍 9 | 10 | ### 内嵌元素(Nested Elements) 11 | **App.jsx** 12 | ```javascript 13 | import React from 'react'; 14 | 15 | class App extends React.Component { 16 | render() { 17 | return ( 18 | <div> 19 | <h1>Header</h1> 20 | <h2>Content</h2> 21 | <p>This is the content!!!</p> 22 | </div> 23 | ); 24 | } 25 | } 26 | 27 | export default App; 28 | ``` 29 | ### 添加属性(Attributes) 30 | 可以添加自定义的属性,不过需要需加前缀data-xxx,如下,给元素添加一个自定义属性data-myattribute <br/> 31 | **App.jsx** 32 | ```javascript 33 | import React from 'react'; 34 | 35 | class App extends React.Component { 36 | render() { 37 | return ( 38 | <div> 39 | <h1>Header</h1> 40 | <h2>Content</h2> 41 | <p data-myattribute = "somevalue">This is the content!!!</p> 42 | </div> 43 | ); 44 | } 45 | } 46 | 47 | export default App; 48 | ``` 49 | ### Js表达式(JavaScript Expressions) 50 | 可以在JSX中嵌入js表达式,只需要用{}来包裹,如下将在浏览器中渲染显示出2 <br/> 51 | **App.jsx** 52 | ```bash 53 | <h1>{1+1}</h1> 54 | ``` 55 | 同样可以在JSX中使用if else表达式 56 | ```javascript 57 | <h1>{i === 1 ? 'True!' : 'False'}</h1> 58 | {condition ? <span>Hello JSX (The condition was true)</span> : null} 59 | ``` 60 | ### 样式(Styling) 61 | 样式使用驼峰式语法,数字后默认px 62 | ```javascript 63 | import React from 'react'; 64 | 65 | class App extends React.Component { 66 | render() { 67 | var myStyle = { 68 | fontSize: 100, 69 | color: '#FF0000' 70 | } 71 | return ( 72 | <div> 73 | <h1 style = {myStyle}>Header</h1> 74 | </div> 75 | ); 76 | } 77 | } 78 | export default App; 79 | ``` 80 | ### 注释(Comments) 81 | 可以用单行//或多行/*...*/来注释,当在子元素中写注释,最好包裹上{} 82 | 83 | ```javascript 84 | import React from 'react'; 85 | class App extends React.Component { 86 | render() { 87 | return ( 88 | <div> 89 | <h1>Header</h1> 90 | {//单行注释...} 91 | {/*多行注释...*/} 92 | </div> 93 | ); 94 | } 95 | } 96 | export default App; 97 | ``` 98 | 99 | ### 不同点 100 | 101 | * 1、HTML标签使用小写,而React组件以**大写**字母为首命名 102 | * 2、`html`的`class`与`for`属性在`js`里是保留字,所以`jsx`里要用别名`className`与`htmlFor` 103 | * 3、checkbox中正确使用checked属性 104 | ```javascript 105 | //在其他前端模板引擎中,可以这么做,因为是拼接字符串 106 | var checkbox = <input type="checkbox" {this.props.selected ? 'checked' : ''} /> 107 | //但在jsx中,这是错误的,因为无法构成键值对,要有个key=value的格式,所以得这样 108 | var checkbox = <input className="cbName" type="checkbox" checked={this.props.selected} /> 109 | ``` 110 | * 4、不能直接写并列的元素 111 | ```javascript 112 | //这样写是错误的 113 | var MyComponent = React.createClass({ 114 | render: function() { 115 | return <div>first div</div><div>second div</div> 116 | } 117 | }) 118 | //因为编译后,return 两个函数调用,就算不报错,也只调用第一个函数,不合意图 119 | var MyComponent = React.createClass({ 120 | render: function() { 121 | return React.createElement('div', null, 'first div') React.createElement('div', null, 'second div') 122 | } 123 | }) 124 | ``` 125 | * 5、jsx要求标签一定要闭合,html5中不强制要求闭合的,在jsx也都要闭合,以便识别 126 | * 6、封装的组件要用大写字母开头,以便跟html标签区分。 127 | -------------------------------------------------------------------------------- /04、state_props/src/jsx/ContactsApp.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react'; 2 | const contactsData = require('./../public/contacts.json'); //获取json数据 3 | 4 | class ContactsAppContainer extends Component { 5 | constructor(){ 6 | super(); 7 | this.state={ 8 | contacts: [] 9 | }; 10 | } 11 | 12 | componentDidMount(){ 13 | this.setState({contacts: contactsData.datas}); 14 | } 15 | 16 | render(){ 17 | return ( 18 | <ContactsApp contacts={this.state.contacts} /> 19 | ); 20 | } 21 | } 22 | 23 | // Renders a SearchBar and a ContactList 24 | // Passes down filterText state and handleUserInput callback as props 25 | class ContactsApp extends Component { 26 | constructor(){ 27 | super(); 28 | this.state={ 29 | filterText: '' 30 | }; 31 | } 32 | 33 | handleUserInput(searchText){ 34 | this.setState({filterText: searchText}) 35 | } 36 | 37 | render(){ 38 | return( 39 | <div> 40 | <SearchBar filterText={this.state.filterText} 41 | onUserInput={this.handleUserInput.bind(this)} /> 42 | <ContactList contacts={this.props.contacts} 43 | filterText={this.state.filterText}/> 44 | </div> 45 | ) 46 | } 47 | } 48 | ContactsApp.propTypes = { 49 | contacts: PropTypes.arrayOf(PropTypes.object) 50 | } 51 | 52 | 53 | // Pure component that receives 2 props from the parent 54 | // filterText (string) and onUserInput (callback function) 55 | class SearchBar extends Component { 56 | handleChange(event){ 57 | this.props.onUserInput(event.target.value) 58 | } 59 | 60 | render(){ 61 | return <input type="search" 62 | placeholder="search" 63 | value={this.props.filterText} 64 | onChange={this.handleChange.bind(this)} /> 65 | } 66 | } 67 | SearchBar.propTypes = { 68 | onUserInput: PropTypes.func.isRequired, 69 | filterText: PropTypes.string.isRequired 70 | } 71 | 72 | // Pure component that receives both contacts and filterText as props 73 | // The component is responsible for actualy filtering the 74 | // contacts before displaying them. 75 | // It's considered a pure component because given the same 76 | // contacts and filterText props the output will always be the same. 77 | class ContactList extends Component { 78 | render(){ 79 | //过滤contacts中数据 80 | let filteredContacts = this.props.contacts.filter( 81 | (contact) => contact.name.indexOf(this.props.filterText) !== -1 82 | ); 83 | return( 84 | <ul> 85 | {filteredContacts.map( 86 | (contact) => <ContactItem key={contact.email} 87 | name={contact.name} 88 | email={contact.email} /> 89 | )} 90 | </ul> 91 | ) 92 | } 93 | } 94 | ContactList.propTypes = { 95 | contacts: PropTypes.arrayOf(PropTypes.object), 96 | filterText: PropTypes.string.isRequired 97 | } 98 | 99 | class ContactItem extends Component { 100 | render() { 101 | return <li>{this.props.name} - - {this.props.email}</li> 102 | } 103 | } 104 | ContactItem.propTypes = { 105 | name: PropTypes.string.isRequired, 106 | email: PropTypes.string.isRequired 107 | } 108 | 109 | export default ContactsAppContainer; 110 | -------------------------------------------------------------------------------- /00、es6-notes/05-array、map、set.md: -------------------------------------------------------------------------------- 1 | * 一、Arrays 2 | * 二、Set 和 WeakSet 3 | * 三、Map 和 WeakMap 4 | * 四、Symbols 5 | 6 | #### 一、Arrays 7 | 1、find 8 | ```javascript 9 | var ary = [1, 5, 10]; 10 | var match = ary.find(item => item > 8); 11 | match; // 10 12 | ``` 13 | 2、findIndex 14 | 返回符合条件第一个index 15 | ```javascript 16 | var ary = [1, 5, 10]; 17 | var match = ary.findIndex(item => item > 3); 18 | match; // 1 19 | ``` 20 | 3、fill填充 21 | ```javascript 22 | var ary = [1, 2, 3, 4, 5]; 23 | ary.fill('a'); 24 | ary; // ['a', 'a', 'a', 'a', 'a'] 25 | 26 | ary.fill('a', 2, 3) // 只需要下表为index的数为 'a' 27 | ``` 28 | 4、copyWithin 29 | ```javascript 30 | var ary = [1, 2, 3, 4]; // we want [1, 2, 1, 2] 31 | 32 | // First parameter as the target (index 2) 33 | // Second parameter is where you copy from (index 0) 34 | // A third parameter would be the stopping point. 35 | ary.copyWithin(2, 0); // [1, 2, 1, 2] 36 | ary.copyWithin(2, 0, 1); // [1, 2, 1, 4] 37 | ary.copyWithin(2, 0, 2); // [1, 2, 1, 2] 38 | 39 | // Can also use negative indexes: 40 | ary.copyWithin(0, -2); // [3, 4, 3, 4] 41 | ``` 42 | 5、of 43 | ```javascript 44 | var ary = new Array(3); //[, , ] 45 | var ofAry = Array.of(3); // [3] 46 | 47 | ary.length; // 3 48 | ofAry.length; // 1 49 | ``` 50 | 6、entries and keys 51 | ```javascript 52 | var a = ['Joe', 'Jim', 'John']; 53 | var entries = a.entries(); 54 | 55 | var firstEntry = entries.next().value; 56 | firstEntry[0]; // 0 (the index) 57 | firstEntry[1]; // 'Joe' (the value) 58 | 59 | // `keys` are the indexes 60 | var firstKey = keys.next().value; 61 | firstKey; // 0 62 | ``` 63 | 7、forEach遍历 和 filter过滤 64 | ```javascript 65 | let arrs = [1, 2, 3]; 66 | arrs.forEach(arr => { 67 | console.log(arr + 1); // 打印出 2 3 4 68 | }); 69 | 70 | arrs = arrs.filter(a => a != 3); 71 | console.log(arrs);// [1, 2] 72 | ``` 73 | 74 | #### 二、Set 和 WeakSet 75 | Set 对象是一组不重复的值,重复的值将被忽略,值类型可以是原始类型和引用类型: 76 | ```javascript 77 | let mySet = new Set([1, 1, 2, 2, 3, 3]); 78 | mySet.size; // 3 79 | mySet.has(1); // true 80 | mySet.add('strings'); 81 | mySet.add({ a: 1, b:2 }); 82 | ``` 83 | WeakSet 对象可以让你在一个集合中保存对象的弱引用,在 WeakSet 中的对象只允许出现一次: 84 | 85 | 86 | #### 三、Map 和 WeakMap 87 | ES6 中两种新的数据结构集:Map 和 WeakMap。事实上每个对象都可以看作是一个 Map。<br/> 88 | 一个对象由多个 key-val 对构成,在 Map 中,任何类型都可以作为对象的 key <br/> 89 | entries 90 | ```javascript 91 | var map = new Map(); 92 | map.set('name', 'Joe'); 93 | var items = map.entries(); 94 | var first = items.next().value; 95 | first[0]; // 'name' 96 | first[1]; // 'Joe' 97 | ``` 98 | values和keys 99 | ```javascript 100 | var map = new Map(); 101 | map.set(1, 'a'); 102 | var values = map.values(); 103 | var first = values.next().value; 104 | first; // 'a' 105 | 106 | var keys = map.keys(); 107 | var firstKey = keys.next().value; 108 | firstKey; // 1 109 | ``` 110 | 111 | #### 四、Symbols 112 | 1、Symbol() <br/> 113 | Symbols 是不可改变并且是第一无二的,可以在任意哈希中作一个key。<br/> 114 | 调用 Symbol() 或者 Symbol(description) 可以创造一个第一无二的符号,<br/> 115 | 但是在全局是看不到的。Symbol() 的一个使用情况是给一个类或者命名空间打上补丁,<br/> 116 | 但是可以确定的是你不会去更新它。比如,你想给 React.Component 类添加一个 refreshComponent 方法,<br/> 117 | 但是可以确定的是你不会在之后更新这个方法: 118 | ```javascript 119 | const refreshComponent = Symbol(); 120 | React.Component.prototype[refreshComponent] = () => { 121 | // do something 122 | } 123 | ``` 124 | 2、Symbol.for(key) 125 | Symbol.for(key) 同样会创造一个独一无二并且不可改变的 Symbol,但是它可以全局看到,<br/> 126 | 两个相同的调用 Symbol.for(key) 会返回同一个 Symbol 类: 127 | ```javascript 128 | Symbol('foo') === Symbol('foo') // false 129 | Symbol.for('foo') === Symbol('foo') // false 130 | Symbol.for('foo') === Symbol.for('foo') // true 131 | ``` 132 | 在另一个库中: 133 | ```javascript 134 | const specialRead = Symbol.for('specialRead'); 135 | 136 | class SomeReadableType { 137 | [specialRead]() { 138 | const reader = createSomeReaderFrom(this); 139 | return reader; 140 | } 141 | } 142 | ``` 143 | -------------------------------------------------------------------------------- /00、es6-notes/06-Promise.md: -------------------------------------------------------------------------------- 1 | * 一、Promise 2 | * 二、Promise基础 3 | * 三、Promise的API 4 | * 四、Promise实战 5 | 6 | #### 一、Promise 7 | 1、`Promise`,首先是一个对象,用来传递异步操作的消息。它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的`API`,可供进一步处理。 <br /> 8 | 9 | 2、`Promise`对象只有三种状态。 <br /> 10 | 11 | * 异步操作“未完成”(pending) 12 | * 异步操作“已完成”(resolved,又称fulfilled) 13 | * 异步操作“失败”(rejected) 14 | 15 | `Promise`对象的最终结果只有两种 <br /> 16 | 17 | * 异步操作成功,Promise对象传回一个值,状态变为resolved。 18 | * 异步操作失败,Promise对象抛出一个错误,状态变为rejected。 19 | 20 | 3、`Promise`的优点:<br /> 21 | 22 | * 让回调函数变成了规范的链式写法,程序流程可以看得很清楚 23 | * 为多个回调函数中抛出的错误统一指定处理方法 24 | * `Promise` 可以让我们远离平行的代码(回调地狱) 25 | ```javascript 26 | step1(function (value1) { 27 | step2(value1, function (value2) { 28 | step3(value2, function (value3) { 29 | }); 30 | }); 31 | }); 32 | }); 33 | ``` 34 | 转变成垂直代码: 35 | ```javascript 36 | (new Promise(step1)) 37 | .then(step2) 38 | .then(step3, value3 => { 39 | // Do something with value3 40 | }); 41 | ``` 42 | 43 | #### 二、Promise基础 44 | 45 | 1、新建Promise <br /> 46 | Promise是一个构造函数(类),可以使用new运算符新建一个实例,然后就可以使用了,构造函数接受一个函数作为参数。 47 | ```javascript 48 | var p = new Promise((resolve, reject) => { 49 | if (/* condition */) { 50 | resolve(/* value */); // fulfilled successfully 51 | } else { 52 | reject(new Error('/* reason */')); // error, rejected 53 | } 54 | }); 55 | p.then((value) => { 56 | console.log('p success', value); 57 | }); 58 | p.catch((reason) => { 59 | console.log(reason); 60 | }); 61 | ``` 62 | 两个处理器,`resolve`(当Promise是 fulfilled 时的回调)和 `reject`(当Promise是 rejected 时的回调)<br /> 63 | 64 | 2、`.then()`方法 65 | 66 | * 当创建好的promise执行完成后,其状态会变成 `resolved` 或者 `reject` 67 | * 可以通过then方法定制状态变化后的回调函数,该方法接受两个参数, 68 | 第一个是异步操作成功处理 `resolved` 状态的回调,另一个是异步操作失败处理 `rejected` 状态的回调: 69 | ```javascript 70 | p.then((val) => console.log("Promise Resolved", val), 71 | (err) => console.log("Promise Rejected", err)); 72 | //ES5写法 73 | p.then(function(value) { 74 | // success 75 | }, function(reason) { 76 | // failure 77 | }); 78 | ``` 79 | 80 | 3、多个promise交互 81 | ```javascript 82 | var previousPromise = new Promise(function(resolve, reject){ 83 | resolve(3); 84 | }); 85 | 86 | var promise = new Promise(function(resolve, reject) { 87 | resolve( previousPromise ); 88 | }); 89 | 90 | promise.then( function(data) { 91 | console.log(data); // 3 92 | }) 93 | ``` 94 | 95 | #### 三、Promise的API 96 | 97 | * 1、Promise.all 98 | Promise.all(iterable) 方法返回一个promise,该promise会在iterable参数内的**所有promise都被解决**后被解决 <br/> 99 | 100 | * 2、Promise.race 101 | Promise.race(iterable)方法返回一个promise,这个promise在iterable中的**任意一个promise被解决或拒绝**后,立刻以相同的解决值被解决或以相同的拒绝原因被拒绝 <br /> 102 | 103 | * 3、Promise.reject 104 | Promise.reject(reason)方法返回一个用reason拒绝的Promise。<br /> 105 | 106 | * 4、Promise.resolve <br /> 107 | Promise.resolve(value)方法返回一个以给定值resolve掉的Promise对象。 <br /> 108 | 109 | #### 四、Promise实战 110 | 111 | 1、综合实战 112 | ```javascript 113 | // 1000ms 后success 114 | var p1 = new Promise((resolve, reject) => { 115 | window.setTimeout(() => {resolve(123);}, 1000); 116 | }); 117 | 118 | p1.then((data) => { 119 | console.log('p1 success', data); 120 | }); 121 | 122 | // 2000ms 后success 123 | var p2 = new Promise((resolve, reject) => { 124 | window.setTimeout(() => {resolve(456);}, 2000); 125 | }); 126 | 127 | p2.then((data) => { 128 | console.log('p2 success', data); 129 | }); 130 | 131 | var pa = Promise.all([p1, p2]); 132 | var pr = Promise.race([p1, p2]); 133 | 134 | pa.then((data) => { 135 | console.log('pa success', data); 136 | }); 137 | 138 | pr.then((data) => { 139 | console.log('pr success', data); 140 | }); 141 | ``` 142 | 上面的代码输出如下: 143 | ``` 144 | // 1000ms 145 | p1 success 123 146 | pr success 123 147 | 148 | // 2000ms 149 | p2 success 456 150 | pa success [123, 456] 151 | ``` 152 | 2、用ajax加载图片 153 | ```javascript 154 | function imgLoad(url) { 155 | return new Promise(function(resolve, reject) { 156 | var request = new XMLHttpRequest(); 157 | request.open('GET', url); 158 | request.responseType = 'blob'; 159 | request.onload = function() { 160 | if (request.status === 200) { 161 | resolve(request.response); 162 | } else { 163 | reject(new Error('图片加载失败:' + request.statusText)); 164 | } 165 | }; 166 | request.onerror = function() { 167 | reject(new Error('发生网络错误')); 168 | }; 169 | request.send(); 170 | }); 171 | } 172 | 173 | var img = document.findElementById("imgId"); 174 | imgLoad("http://xxxx.com").then(data => { 175 | img.src = data; 176 | }); 177 | ``` 178 | 3、项目中请求实战 179 | ```javascript 180 | let urls = [ 181 | '/api/commits', 182 | '/api/issues/opened', 183 | '/api/issues/completed', 184 | '/api/pullrequests' 185 | ]; 186 | 187 | let promises = urls.map((url) => { 188 | return new Promise((resolve, reject) => { 189 | $.ajax({ url: url }) 190 | .done((data) => { 191 | resolve(data); 192 | }); 193 | }); 194 | }); 195 | 196 | Promise.all(promises) 197 | .then((results) => { 198 | // Do something with results of all our promises 199 | }); 200 | ``` 201 | -------------------------------------------------------------------------------- /00、es6-notes/01-变量和参数.md: -------------------------------------------------------------------------------- 1 | 2 | * 一、const、let与原var 3 | * 二、对象和数组解构(Destructuring) 4 | * 三、参数默认值 5 | * 四、Spread展开 / Rest剩余 操作符 6 | * 五、模板语法和分隔符 7 | 8 | #### 一、const、let与原var <br /> 9 | 1、相比`es5`的`var`是相对函数作用域范围,`const`和`let`都是相对块级作用域范围 <br /> 10 | 2、`const` 在声明时必须被赋值, 而且只读,不能重新赋值 <br /> 11 | 3、`let` 和 `const` 关键词声明的变量不具备变量提升(hoisting)特性 <br /> 12 | 4、用块级作用域代替`IIFES`(创造一个内部的作用域) <br /> 13 | ```javascript 14 | //ES6 15 | const a = 1 16 | let b = 'foo' 17 | // a = 2 // Uncomment me!, "a" is read-only 18 | // b = 'bar' 19 | if (true) { 20 | const a = 3;//此a和上面的a是两个不同变量 21 | console.log(a); // 3 22 | } 23 | console.log(a); // 1 24 | 25 | for(let j = 0; j < 10; j++){ 26 | 27 | } 28 | console.log(j); // ReferenceError: j is not defined 29 | 30 | const c;//unknown: Unexpected token 31 | ``` 32 | #### 二、对象和数组解构(Destructuring) 33 | ```javascript 34 | let x = 2; 35 | let y = 3; 36 | [x, y] = [y, x]; // x is now 3, and y is now 2 37 | 38 | function foo() { 39 | return [1,2,3]; 40 | } 41 | let arr = foo(); // [1,2,3] 42 | 43 | let [ , b, c] = foo(); 44 | console.log(b, c); //2 3 45 | 46 | function bar() { 47 | return { 48 | x: 4, 49 | y: 5, 50 | z: 6 51 | }; 52 | } 53 | let {x:x, y: y, z: z} = bar(); 54 | //let {x, y, z} = bar(); //或者省略写 55 | console.log(x, y, z); // 4 5 6 56 | 57 | 58 | let doSomething = function() { 59 | return { 60 | firstName: "Charles", 61 | lastName: "Bronson", 62 | handles: { 63 | twitter: "@NoDice", 64 | facebook: "bronson69" 65 | } 66 | }; 67 | }; 68 | 69 | let { firstName, lastName, handles:{twitter} } = doSomething(); 70 | 71 | console.log(twitter);//@NoDice 72 | ``` 73 | The old way when working with a function: 74 | ```javascript 75 | let doSomething = function(url, config){ 76 | return config.data; // "test" 77 | }; 78 | 79 | var config = { data: "test", cache: false } 80 | let result = doSomething("api/test", config); 81 | ``` 82 | 解构参数新方式 83 | ```javascript 84 | let doSomething = function(url, {data, cache}){ 85 | return data; // `test` comes directly from the `data` property 86 | }; 87 | 88 | let result = doSomething("api/test", {data: "test", cache: false}); 89 | ``` 90 | **对象解构** 91 | ```javascript 92 | let luke = { occupation: 'jedi', father: 'anakin' }; 93 | let {occupation, father} = luke; 94 | 95 | console.log(occupation); // 'jedi' 96 | console.log(father); // 'anakin' 97 | ``` 98 | #### 三、参数默认值 99 | 无参的老处理方式如下 100 | ```javascript 101 | var doSomething = function(name){ 102 | return name || "Taylor"; 103 | }; 104 | var a = doSomething();//或传入0、""、null、undefined都等于"Taylor" 105 | console.log(a); 106 | ``` 107 | ES6新方式 108 | ```javascript 109 | var doSomething = function(name="Taylor"){ 110 | return name; 111 | }; 112 | ``` 113 | 【注意】ES6和原设置默认的区别如下 114 | ```javascript 115 | let result = doSomething(); // "Taylor" 116 | let result = doSomething(""); // Undefined 117 | let result = doSomething(undefined); // "Taylor" 118 | let result = doSomething("Colleen"); // "Colleen" 119 | let result = doSomething(null); // null 120 | ``` 121 | Combining Concepts: 122 | ```javascript 123 | let doSomething = function(a = 1, b = 2, c = 3){ 124 | return [a, b, c]; 125 | }; 126 | 127 | let [a,b,c] = doSomething(5, undefined); // a = 5, b = 2, c = 3 128 | ``` 129 | 与解构(destructuring)的例子: 130 | ```javascript 131 | let doSomething = function(url, {data = "Taylor", cache = true}){ 132 | return data; 133 | }; 134 | 135 | let result = doSomething("api/test", { cache: false }); // "Taylor" is returned (and `cache` is `false` inside the function) 136 | ``` 137 | #### 四、Spread展开 / Rest剩余 操作符 138 | Spread / Rest 操作符指的是 ...,具体是 Spread 还是 Rest 需要看上下文语境。 <br/> 139 | 1、当被用于迭代器中时,它是一个 Spread 操作符: <br/> 140 | ```javascript 141 | function foo(x,y,z) { 142 | console.log(x,y,z); 143 | } 144 | let arr = [1,2,3]; 145 | foo(...arr); // 1 2 3 【数组展开了有木有!!!】 146 | 147 | var a = [4, 5, 6]; 148 | var b = [1, 2, 3, ...a, 7, 8, 9]; //b is now [1, 2, 3, 4, 5, 6, 7, 8, 9] 149 | 150 | let num1 = [1, 2, 3]; 151 | let num2 = [0, ...num1]; 152 | console.log(num1); //[1, 2, 3]; 153 | console.log(...num1); //1 2 3 154 | console.log(num2); //[0, 1, 2, 3]; 155 | ``` 156 | 2、当被用于函数传参时,是一个 Rest 操作符: <br/> 157 | ```javascript 158 | function foo(name, ...args) { 159 | console.log(args); // [1, 2, 3, 4, 5] 160 | console.log(...args); // 1 2 3 4 5 161 | } 162 | var a = foo("Taylor", 1, 2, 3, 4, 5); 163 | ``` 164 | #### 五、模板语法和分隔符 165 | ${ ... } 用来渲染一个变量, 166 | ```javascript 167 | let category = "music"; 168 | let id = 2112; 169 | //` 作为分隔符 170 | let url= `http://apiserver/${category}/${id}`; 171 | 172 | //模版字符串 可以支持换行并且不需要额外的处理: 173 | let text = ( `cat 174 | dog 175 | nickelodeon` 176 | ); 177 | ``` 178 | **带标签的模板字符串** 179 | ```javascript 180 | let one = '1', two = '2'; 181 | funcNum = (strings, ...values) => { 182 | console.log(strings); 183 | console.log(values); 184 | //输出字符串 185 | let resultStr = ''; 186 | for(let i = 0; i < values.length; i++) { 187 | resultStr += strings[i]; 188 | resultStr += values[i]; 189 | } 190 | resultStr += strings[strings.length - 1]; 191 | console.log(resultStr); 192 | return resultStr; 193 | 194 | 195 | } 196 | let nums = funcNum`数字有\n ${one} 与 ${two} !`; 197 | console.log(nums); 198 | ``` 199 | 打印输出如下 200 | ``` 201 | //1、console.log(strings); 202 | ["数字有 203 | ", " 与 ", " !"] 204 | //2、console.log(values); 205 | ["1", "2"] 206 | //3、console.log(resultStr); 207 | "数字有 208 | 1 与 2 !" 209 | //4、console.log(nums); 210 | "数字有 211 | 1 与 2 !" 212 | ``` 213 | -------------------------------------------------------------------------------- /00、es6-notes/03-FunctionalJS函数.md: -------------------------------------------------------------------------------- 1 | * 一、箭头函数=> 2 | * 二、箭头作为异步callback 3 | * 三、迭代器(Iterators) 4 | * 四、生成器(Generators) 5 | 6 | #### 一、箭头函数(Arrow Functions) <br /> 7 | [《箭头函数》链接](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions) <br /> 8 | 1、基础语法 9 | ```javascript 10 | (param1, param2, …, paramN) => { statements } 11 | 12 | (param1, param2, …, paramN) => expression 13 | // 相当于: => { return expression; } 14 | 15 | // 如果只有一个参数,圆括号是可选的: 16 | (singleParam) => { statements } 17 | singleParam => { statements } 18 | 19 | // 无参数的函数需要使用圆括号: 20 | () => { statements } 21 | ``` 22 | 2、高级语法 23 | ```javascript 24 | // 返回对象字面量时应当用圆括号将其包起来: 25 | params => ({foo: bar}) 26 | 27 | // 支持 Rest parameters 和 default parameters: 28 | (param1, param2, ...rest) => { statements } 29 | (param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements } 30 | 31 | // Destructuring within the parameter list is also supported 32 | var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c; 33 | f(); // 6 34 | ``` 35 | 3、更短的函数 36 | ```javascript 37 | var arr = [ 38 | "Hydrogen", 39 | "Helium", 40 | "Lithium", 41 | "Beryl­lium" 42 | ]; 43 | var a2 = arr.map(function(a){ return a.length }); 44 | //更短的函数写法 45 | var a3 = arr.map( s => s.length );//[8, 6, 7, 10] 46 | ``` 47 | 4、箭头函数中`this`总是绑定指向对象自身 <br /> 48 | 解决了ES5中需要给回调函数维护一个词法作用域的上下文this(var that = this;) <br/> 49 | ```javascript 50 | //ES5中 51 | var age = 100; 52 | function Person() { 53 | this.age = 0; 54 | 55 | setInterval(function growUp() { 56 | // 在非严格模式下,growUp() 函数的 this 指向 window 对象 57 | this.age++; 58 | console.log(this.age);//101,102... 59 | }, 1000); 60 | } 61 | var person = new Person(); 62 | 63 | //ES6实现 64 | function Person(){ 65 | this.age = 0; 66 | 67 | setInterval(() => { 68 | // |this| 指向 person 对象 69 | this.age++; 70 | console.log(this.age); //1,2... 71 | }, 1000); 72 | } 73 | var person = new Person(); 74 | ``` 75 | 5、使用 call 或 apply 调用 <br /> 76 | 由于 this 已经在词法层面完成了bound,通过 call() 或 apply() 方法调用一个函数时,只是传入了参数而已,对 this 并没有什么影响: 77 | ```javascript 78 | var adder = { 79 | base : 1, 80 | 81 | add : function(a) { 82 | var f = v => v + this.base; 83 | return f(a); 84 | }, 85 | 86 | addThruCall: function(a) { 87 | var f = v => v + this.base; 88 | var b = { 89 | base : 2 90 | }; 91 | 92 | return f.call(b, a); 93 | } 94 | }; 95 | 96 | console.log(adder.add(1)); // 输出 2 97 | console.log(adder.addThruCall(1)); // 仍然输出 2(而不是3) 98 | ``` 99 | 6、arguments 的词法 <br /> 100 | 箭头函数不会在其内部暴露出 arguments 对象: arguments.length, arguments[0], arguments[1] 等等,都不会指向箭头函数的 arguments,而是指向了箭头函数所在作用域的一个名为 arguments 的值(如果有的话,否则,就是 undefined) 101 | ```javascript 102 | var arguments = 42; 103 | var arr = () => arguments; 104 | 105 | arr(); // 42 106 | 107 | function foo() { //foo 的arguments 108 | var f = () => arguments[0]; // foo's implicit arguments binding 109 | return f(2); 110 | } 111 | 112 | foo(1); // 1 113 | ``` 114 | 箭头函数没有自己的 arguments 对象,不过在大多数情形下,rest参数可以给出一个解决方案: 115 | ```javascript 116 | function foo() { 117 | var f = (...args) => args[0]; 118 | return f(2); 119 | } 120 | 121 | foo(1); // 2 122 | ``` 123 | **更多示例** 124 | ```javascript 125 | // 一个空箭头函数,返回 undefined 126 | let empty = () => {}; 127 | 128 | (() => "foobar")() // 返回 "foobar" 129 | 130 | var simple = a => a > 15 ? 15 : a; 131 | simple(16); // 15 132 | simple(10); // 10 133 | 134 | let max = (a, b) => a > b ? a : b; 135 | 136 | // Easy array filtering, mapping, ... 137 | 138 | var arr = [5, 6, 13, 0, 1, 18, 23]; 139 | var sum = arr.reduce((a, b) => a + b); // 66 140 | var even = arr.filter(v => v % 2 == 0); // [6, 0, 18] 141 | var double = arr.map(v => v * 2); // [10, 12, 26, 0, 2, 36, 46] 142 | ``` 143 | 144 | #### 二、箭头作为异步callback 145 | ```javascript 146 | this.name = "Taylor"; 147 | 148 | ajaxCall("aUrl", (response) => { 149 | this.name = response.data; 150 | }); 151 | ``` 152 | #### 三、迭代器(Iterators) 153 | 迭代器允许每次访问数据集合的一个元素,当指针指向数据集合最后一个元素是,迭代器便会退出。它提供了 next() 函数来遍历一个序列,这个方法返回一个包含 done 和 value 属性的对象。 <br/> 154 | ES6 中可以通过 Symbol.iterator 给对象设置默认的遍历器,无论什么时候对象需要被遍历,执行它的 @@iterator 方法便可以返回一个用于获取值的迭代器。<br/> 155 | 数组默认就是一个迭代器: 156 | ```javascript 157 | var arr = [11,12,13]; 158 | var itr = arr[Symbol.iterator](); 159 | 160 | itr.next(); // { value: 11, done: false } 161 | itr.next(); // { value: 12, done: false } 162 | itr.next(); // { value: 13, done: false } 163 | 164 | itr.next(); // { value: undefined, done: true } 165 | ``` 166 | 你可以通过 [Symbol.iterator]() 自定义一个对象的迭代器。 167 | #### 四、生成器(Generators) 168 | 就像 Promises 可以帮我们避免回调地狱,Generators 可以帮助我们让代码风格更整洁-<br/> 169 | -用同步的代码风格来写异步代码,它本质上是一个可以暂停计算并且可以随后返回表达式的值的函数。<br/> 170 | Generator 函数是 ES6 的新特性,它允许一个函数返回的可遍历对象生成多个值。<br/> 171 | 在使用中你会看到 * 语法和一个新的关键词 yield: 172 | ```javascript 173 | function* infiniteNumbers() { 174 | var n = 1; 175 | while (true){ 176 | yield n++; 177 | } 178 | } 179 | var numbers = infiniteNumbers(); // returns an iterable object 180 | 181 | numbers.next(); // { value: 1, done: false } 182 | numbers.next(); // { value: 2, done: false } 183 | numbers.next(); // { value: 3, done: false } 184 | ``` 185 | 每次执行 yield 时,返回的值变为迭代器的下一个值。 186 | ```javascript 187 | let numbers = function*(start, end) { 188 | for(let i = start; i <= end; i++) { 189 | console.log(i); 190 | yield i; 191 | } 192 | }; 193 | //使用"for of" with a Generator 194 | let sum = 0; 195 | for(let n of numbers(1,5)){ 196 | sum += n; 197 | console.log("next"); 198 | } 199 | 200 | sum; // 15 201 | ``` 202 | 可以利用 Generators 来用同步的方式来写异步操作: 203 | ```javascript 204 | // Hiding asynchronousity with Generators 205 | function getRequest(url) { 206 | getJSON(url, function(response) { 207 | generator.next(response); 208 | }); 209 | } 210 | ``` 211 | 这里的 generator 函数将会返回需要的数据: 212 | ```javascript 213 | function* getData() { 214 | var entry1 = yield getRequest('http://some_api/item1'); 215 | var data1 = JSON.parse(entry1); 216 | var entry2 = yield getRequest('http://some_api/item2'); 217 | var data2 = JSON.parse(entry2); 218 | } 219 | ``` 220 | 通过 yield,我们可以保证 entry1 有 data1 中我们需要解析并储存的数据。<br /> 221 | 虽然我们可以利用 Generators 来用同步的方式来写异步操作,但是确认错误的传播变得不再清晰,我们可以在 Generators 中加上 Promise: 222 | ```javascript 223 | function request(url) { 224 | return new Promise((resolve, reject) => { 225 | getJSON(url, resolve); 226 | }); 227 | } 228 | ``` 229 | 然后我们写一个函数逐步调用 next 并且利用 request 方法产生一个 Promise: 230 | ```javascript 231 | function iterateGenerator(gen) { 232 | var generator = gen(); 233 | (function iterate(val) { 234 | var ret = generator.next(); 235 | if(!ret.done) { 236 | ret.value.then(iterate); 237 | } 238 | })(); 239 | } 240 | ``` 241 | 在 Generators 中加上 Promise 之后我们可以更清晰的使用 Promise 中的 .catch 和 reject来捕捉错误,让我们使用新的 Generator,和之前的还是蛮相似的: 242 | ```javascript 243 | iterateGenerator(function* getData() { 244 | var entry1 = yield request('http://some_api/item1'); 245 | var data1 = JSON.parse(entry1); 246 | var entry2 = yield request('http://some_api/item2'); 247 | var data2 = JSON.parse(entry2); 248 | }); 249 | ``` 250 | --------------------------------------------------------------------------------