ES6组件写法:
每个组件实例都有自己的声明周期。
class App extends Component{
render(){
return (<div>App1</div>);
}
componentWillMount(){
console.log('app1 WillMount');
}
componentDidMount(){
console.log('app1 DidMount');
}
componentWillUpdate(){
console.log('app1 WillUpdate');
}
componentWillUnmount(){
console.log('app1 WillUnmount');
}
}
函数式组件写法:
可以理解这种写法是ES6组件的一种简写。
const App2 = () => {
return (<div>App2</div>);
}
JS和HTML混写:
支持字符串,数组等的渲染,不支持对象object的渲染。实例中展示了条件渲染。
import React, {Component} from 'react';
class List extends Component {
render(){
let name = 'David';
let arr1 = ['A', 'B', 'C', 'D'];
let arr2 = [<p>Nice</p>, <p>Boy</p>];
let obj = {a: 1, b: 2};
let showTitle = false;
return (<div>{arr1.map((item, index) => {
if((index+1) % 2 !== 1) {
return item;
}
})}
<h2>title</h2>
<div>{showTitle && <h3>Title</h3>}</div>
<h2>no title</h2>
<div>{showTitle ? <h3>Title</h3> : <h3>No Title</h3>}</div>
</div>
);
}
}
export default List;
React虚拟DOM原理:
https://www.cnblogs.com/zhuzhenwei918/p/7271305.html
虚拟DOM:
1. 把jsx编译成js;
- 把浏览器构建DOM树的工作交给JS,让JS去构建DOM树;
- 把结构数据传给React Render方法,将数据渲染出来;
Tree-Diff算法:
虚拟DOM树发生改变的3种情况:
1. DOM标签发生变化:
变为,把DIV标签删掉,把新标签SPAN添加进去;
- 组件发生变化:
变为 组件,把Header组件删掉,然后添加Content组件; - 列表(数组等)渲染:要为组件添加key的属性,而且此属性要唯一,以此优化渲染性能;
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import * as serviceWorker from './serviceWorker';
import Filter from './filter/index'
import List from './list/index'
class Header extends Component {
render(){
return (<div>Header</div>);
}
componentDidMount(){
console.log('Header Mount');
}
componentWillUnmount(){
console.log('Header WillUnmount');
}
}
class Content extends Component {
render(){
return (<div>Content</div>);
}
componentDidMount(){
console.log('Content Mount');
}
componentWillUnmount(){
console.log('Content WillUnmount');
}
}
class App extends Component{
constructor(props){
super(props);
this.state = {
bool: true
};
}
// 修改state 的bool的值,然后Header会被卸载,COntent会被挂载;
render(){
return (<div>
{ this.state.bool ? <Header/> : <Content/> }
</div>);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
serviceWorker.unregister();
Notes:
渲染Item组件时,如果没有给key,当state按示例中变化时,会有如下的日志输出:
React Will Update
Vue Will Update
Angular WillUnmount
当指定key后,输出日志为:
Vue Will Update
Angular Will Update
React WillUnmount
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import * as serviceWorker from './serviceWorker';
class Item extends Component {
render(){
return (<div>{this.props.item}</div>);
}
componentWillMount(){
console.log(this.props.item + ' Will Mount');
}
componentWillUpdate(){
console.log(this.props.item + ' Will Update');
}
componentDidMount(){
console.log(this.props.item + ' Mount');
}
componentWillUnmount(){
console.log(this.props.item + ' WillUnmount');
}
}
class List extends Component {
render(){
return (<div>{this.props.list.map((item) => <Item key={item} item={item}/>)}</div>);
}
componentWillMount(){
console.log('List Will Mount');
}
componentDidMount(){
console.log('List Mount');
}
componentWillUnmount(){
console.log('List WillUnmount');
}
}
class App extends Component{
constructor(props){
super(props);
this.state = {
list: ['Vue', 'Angular', 'React']
};
}
render(){
return (<div>
<List list={this.state.list}/>
<input type='button' onClick={this.change.bind(this)} value='Change'/>
</div>);
}
componentWillMount(){
console.log('App Will Mount');
}
componentDidMount(){
console.log('App Mount');
}
componentWillUnmount(){
console.log('App WillUnmount');
}
change(){
this.setState({list: ['Angular', 'React']});
}
}
ReactDOM.render(<App />, document.getElementById('root'));
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
总结:
1. React通过制定大胆的Diff策略,将O(n3)复杂度的问题转换成O(n)复杂度的问题;
- React 通过分层求异的策略,对tree diff进行算法优化;
- React 通过相同类生成相似树形结构,不同类生成不同树形结构的策略对component diff进行算法优化;
- React 通过设置唯一key的策略,对element diff进行算法优化;