react
1.key
key是唯一标识,react作diff算法时会匹配v-dom,比较key来比较元素,列表里面的每一项都应该有一个永久并且唯一的属性
2.refs
//以前refs可以获得元素,现在是回调函数
ref={(input) => { this.textInput = input; }}
3.e.nativeEvent
4.扩展属性
function App2() {
const props = {firstName: 'Ben', lastName: 'Hector'};
return <Greeting {...props} />;
}
5.react事件变动
1.原生onInput由onChange代替
2.CheckBox Radio 用click代替onchange
3.可控组件与不可控组件
6.reactAPI
// React命名空间
//1.React.createClass class ... extends Component
//2.React.Component
//3.React.createElement
//4.React.cloneElement
//5.React.createFactory
//6.React.isValidElement
//ReactDOM命名空间
//1.ReactComponent ReactDOM.render(ReactElement,DOMElement,cb)
//2.Boolean ReactDOM.unmountComponentAtNode(document.getElementById('example'));
//3.DOMElement findDOMNode(ReactComponent component)
//ReactDOMServer
//1.ReactDOMServer.renderToString
//2.ReactDOMServer.renderToStaticMarkup
//Children
//1.React.Children.map()
//2.React.Children.forEach()
//3.React.Children.count()
//4.React.Children.only()
//5.React.Children.toArray()
7.组件生命周期
// 首次实例化
// getDefaultProps
// getInitialState 只会调用一次,填充State
// componentWillMount 此方法内调用setState,render将会感知
// render
// componentDidMount
// 存在期
// 组件已存在时的状态改变
// componentWillReceiveProps 函数接受新的props时调用,在此函数中调用setState不会二次渲染
// shouldComponentUpdate(nextProps,nextState) 若返回false则组件render,componentWillUpdate,componentDidUpdate,调用被忽略
// componentWillUpdate 在接收到新的state与props之前调用,不可调用setState
// render
// 必选的方法,创建虚拟DOM,该方法具有特殊的规则:
// 只能通过this.props和this.state访问数据
// 可以返回null、false或任何React组件
// 只能出现一个顶级组件(不能返回数组)
// 不能改变组件的状态
// 不能修改DOM的输出
// componentDidMount
// 真实的DOM被渲染出来后调用,在该方法中可通过this.getDOMNode()访问到真实的DOM元素。此时已可以使用其他类库来操作这个DOM。
// 在服务端中,该方法不会被调用。
// 存在期
// 组件已存在时的状态改变
// componentWillReceiveProps 父组件更改子组件时调用,在此函数中调用setState不会二次渲染
// shouldComponentUpdate(nextProps,nextState) 若返回false则组件render,componentWillUpdate,componentDidUpdate,调用被忽略
// componentWillUpdate 在接收到新的state与props之前调用,不可调用setState,此时不允许更新props或state
// render
// componentDidUpdate 此时允许更新props或state
// 销毁&清理期
// componentWillUnmount 清理a
void componentWillReceiveProps(
object nextProps, object nextContext
)
boolean shouldComponentUpdate(
object nextProps, object nextState, object nextContext
)
void componentWillUpdate(
object nextProps, object nextState, object nextContext
)
void componentDidUpdate(
object prevProps, object prevState, object prevContext
)
8.组件通信
1.父->子 props
2.子->父 回掉函数
3.无关系组件:redux
9.其他组件属性:
class Other extends Component {
static displayName = 'MyComponent';
static propTypes = {
prop1: React.PropTypes.string
};
static get defaultProps() {
return {
prop1: 1
}
}
}
10.高阶组件
//高阶组件
import React, { Component } from 'react';
const propsProxyHoc = WrappedComponent => class extends Component {
handleClick() {
console.log('我是通用的');
}
render() {
return (<WrappedComponent
{...this.props}
handleClick={this.handleClick}
/>);
}
};
export default propsProxyHoc;
//使用高阶组件
import React, { Component } from 'react';
import simpleHoc from './H';
class Usual extends Component {
render() {
this.props.handleClick();
console.log(this.props, 'props');
return (
<div>
Usual
</div>
)
}
}
export default simpleHoc(Usual);
react-router-dom
<<<<<<< HEAD
1.BrowserRouter
1.basename:string
2.getUserConfirmation:fun
3.forceRefresh
4.keyLength:number
5.children:node
2.Route
1.component 若传旨为内联函数将出现重复装载
2.render
3.children
const ListItemLink = ({ to, ...rest }) => (
<Route path={to} children={({ match }) => (
<li className={match ? 'active' : ''}>
<Link to={to} {...rest} />
</li>
)}
)
````
<div class="se-preview-section-delimiter"></div>
###对应的props是
<div class="se-preview-section-delimiter"></div>
####1.match
<div class="se-preview-section-delimiter"></div>
####2.location
<div class="se-preview-section-delimiter"></div>
####3.history
<div class="se-preview-section-delimiter"></div>
###Route其他属性
<div class="se-preview-section-delimiter"></div>
####4.path="/usr/:id"
<div class="se-preview-section-delimiter"></div>
####5.exact
<div class="se-preview-section-delimiter"></div>
####6.strict
<div class="se-preview-section-delimiter"></div>
##3.Link
<div class="se-preview-section-delimiter"></div>
####1.to:string
<div class="se-preview-section-delimiter"></div>
####2.to:object
<div class="se-preview-section-delimiter"></div>
####3.replace:bool 点击链接后将使用新地址替换掉上一次访问的地址
<div class="se-preview-section-delimiter"></div>
##4.NavLink
<div class="se-preview-section-delimiter"></div>
####1.activeClassName:string
<div class="se-preview-section-delimiter"></div>
####2.activeStyle:object
<div class="se-preview-section-delimiter"></div>
####3.exact:bool
<div class="se-preview-section-delimiter"></div>
####4.strict:bool
<div class="se-preview-section-delimiter"></div>
####5.isActive:fun 决定导航是否激活,或者在导航激活时候做点别的事情。不管怎样,它不能决定对应页面是否可以渲染
<div class="se-preview-section-delimiter"></div>
##5.Switch渲染内部第一个元素 <Switch> 下的子节点只能是 <Route> 或 <Redirect> 元素
<div class="se-preview-section-delimiter"></div>
##6.Redirect
<div class="se-preview-section-delimiter"></div>
####1.to:string
<div class="se-preview-section-delimiter"></div>
####2.to:object
<div class="se-preview-section-delimiter"></div>
####3.push:bool
<div class="se-preview-section-delimiter"></div>
####4.from:string
<div class="se-preview-section-delimiter"></div>
##7.Prompt
<div class="se-preview-section-delimiter"></div>
####1.message:string 离开时弹出的提示
<div class="se-preview-section-delimiter"></div>
####2.message:fun 离开时执行的回调函数
<div class="se-preview-section-delimiter"></div>
####3.when:bool 启用条件
<div class="se-preview-section-delimiter"></div>
##react-router-dom案列
<div class="se-preview-section-delimiter"></div>
###https://reacttraining.com/react-router/web/guides/philosophy
<div class="se-preview-section-delimiter"></div>
#Flux
<div class="se-preview-section-delimiter"></div>
####1.View: 视图层
<div class="se-preview-section-delimiter"></div>
####2.Action(动作):视图层发出的消息(比如mouseClick)
<div class="se-preview-section-delimiter"></div>
####3.Dispatcher(派发器):用来接收Actions、执行回调函数
<div class="se-preview-section-delimiter"></div>
####4.Store(数据层):用来存放应用的状态,一旦发生变动,就提醒Views要更新页面
<div class="se-preview-section-delimiter"></div>
####Action---Dispatcher---Store---View---Action
<div class="se-preview-section-delimiter"></div>
###1.view:smart组件
<div class="se-preview-section-delimiter"></div>
```javascript
var MyButton = function(props) {
var items = props.items;
var itemHtml = items.map(function (listItem, i) {
return <li key={i}>{listItem}</li>;
});
return <div>
<ul>{itemHtml}</ul>
<button onClick={props.onClick}>New Item</button>
</div>;
};
2.view:木偶组件
var React = require('react');
var ListStore = require('../stores/ListStore');
var ButtonActions = require('../actions/ButtonActions');
var MyButton = require('./MyButton');
var MyButtonController = React.createClass({
getInitialState: function () {
return {
items: ListStore.getAll()
};
},
componentDidMount: function() {
ListStore.addChangeListener(this._onChange);
},
componentWillUnmount: function() {
ListStore.removeChangeListener(this._onChange);
},
_onChange: function () {
this.setState({
items: ListStore.getAll()
});
},
createNewItem: function (event) {
ButtonActions.addNewItem('new item');
},
render: function() {
return <MyButton
items={this.state.items}
onClick={this.createNewItem}
/>;
}
});
module.exports = MyButtonController;
3.action:
var AppDispatcher = require('../dispatcher/AppDispatcher');
var ButtonActions = {
addNewItem: function (text) {
AppDispatcher.dispatch({
actionType: 'ADD_NEW_ITEM',
text: text
});
},
};
module.exports = ButtonActions;
4.Dispatcher:
var Dispatcher = require('flux').Dispatcher;
var AppDispatcher = new Dispatcher();
var ListStore = require('../stores/ListStore');
AppDispatcher.register(function (action) {
switch(action.actionType) {
case 'ADD_NEW_ITEM':
ListStore.addNewItemHandler(action.text);
ListStore.emitChange();
break;
default:
// no op
}
});
module.exports = AppDispatcher;
5.Store:
var EventEmitter = require('events').EventEmitter;
// var assign = require('object-assign');
var ListStore = Object.assign({}, EventEmitter.prototype, {
items: [],
getAll: function () {
return this.items;
},
addNewItemHandler: function (text) {
this.items.push(text);
},
emitChange: function () {
this.emit('change');
},
addChangeListener: function(callback) {
this.on('change', callback);
},
removeChangeListener: function(callback) {
this.removeListener('change', callback);
}
});
module.exports = ListStore;
Redux
(1)Web 应用是一个状态机,视图与状态是一一对应的。
(2)所有的状态,保存在一个对象里面。
1.React Component
smart组件
class Counter extends Component {
render() {
const { value, onIncrement } = this.props;
return (<p>Clicked: {value} times<button onClick={onIncrement}>+</button></p>)
}
}
木偶组件
class Counter extends Component {
render() {
const { value, onIncrement } = this.props;
return (<p>Clicked: {value} times<button onClick={onIncrement}>+</button></p>)
}
}
class App extends Component{
constructor(...props){
super(...props);
this.state = {
value:store.getState()
}
}
onIncrement = () => store.dispatch(increaseAction);
componentDidMount(){
let t = this;
store.subscribe(function () {
t.setState({
value:store.getState()
});
});
}
render(){
return (
<Counter
value={this.state.value}
onIncrement={this.onIncrement}
/>
);
}
}
2.Action
const increaseAction = { type: 'INCREMENT' };
3.Reducer
let counter = (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1;
default:
return state
}
};
4.Store
const store = createStore(counter);