reactjs学习手记(1)

来源:互联网 发布:大数据 侦查 反贪 编辑:程序博客网 时间:2024/05/15 06:40

react课程概要

什么是React

开发背景

facebook推出的,需要解决的问题    构建数据不断变化的大型应用    数据变化-->大量dom操作            -->逻辑变化简单声明式React的核心是组建,组建的设计目的是提高代码复用率,降低测试难度和代码复杂度    提高代码复用率:组建将数据和逻辑封装,类似面向对象中的类。    降低测试难度:组建搞内聚低耦合,很容易对单个组建进行测试。    降低代码的复杂度:直观的语法,提高代码的可阅读性。React Native 构件移动端应用

React开发环境搭建

下载Facebook官方的基础代码

https://github.com/facebook/react/releases

常用的编辑器及插件的配置

CodeKit、Sublime Text 2/3、、、推荐Sublime Text 3插件:Emmet、HTML-CSS-JS Prettify,Spacegray模板环境:nodejs

Emmet语法介绍

子代: >     div>ul>li兄弟: +    div+p+bq父代: ^    div+div>p>span+em^bq重复: *    ul>li*5成组: ()    (div>dl>(dt+dd)*3)+footer>pid  : #    div#header+div.pageclass:.属性: []    div[title="Hello" colspan="3"]demo ```    (div+p#test1>span.test2.test3)*5+p[name="hello"]>div.test4^a*5```

编写第一个React程序

React程序结构

HTML+CSS+(JS+JSX)html:5

修改代码

<!DOCTYPE html><html lang="zh-cn"><head>    <meta charset="UTF-8">    <title>Hello World</title></head><body>    <script src="./react.js"></script>    <script src="./JSXTransformer.js"></script>    <script type="text/jsx">        var Hello = React.createClass({     //注意,首字母必须大写,否则会jsx当作html自带元素            render: function(){                return <p>Hello World</p>            }        });        React.render(<Hello></Hello>,document.body);    </script></body></html>

#注意

元素名字首字母必须大写,否则会jsx当作html自带元素

查看改动效果

用浏览器打开即可

#最新版没有jsx?

jsx语法及特点介绍 - 课程概要

什么是jsx

jsx的发展历程

JSX = JavaScript XML此JSX非彼JSX

基于ECMAScript的一种新特性

一种定义带属性树结构的语法

JSX不是XML或HTML 也不是一种限制

使用react.js不必须使用jsx

优点

类XML语法,容易接受增强JS语义结构清晰抽象程度高(屏蔽掉所有的手动DOM操作)core代码模块化

如何使用jsx

jsx语法

本质上是js,但是可以直接写html标签首字母大小写嵌套求值表达式(js本身的特性)驼峰命名html-->htmlFor和class-->className

注释

// 或/**/

css

var Hello = React.createClass({     //注意,首字母必须大写,否则会jsx当作html自带元素            render: function(){                return <p>Hello World</p>            }        });React.render(<Hello></Hello>,document.body);var style ={    font-color:'red',    border:1px}<div style={style}>     //嵌套Hello嵌套到了一个div中<Hello></Hello></div>

嵌套

条件判断的四种写法

1 三元表达式

var Hello = React.createClass({     //注意,首字母必须大写,否则会jsx当作html自带元素    render: function(){        return <p>Hello {this.props.name ? this.props.name : "World"}</p>    }});

2 直接使用变量

var Hello = React.createClass({     //注意,首字母必须大写,否则会jsx当作html自带元素    getName: function(){        if(this.props.name)            return this.props.name        else            return "world";    }    render: function(){        var name = this.getName();        return <p>Hello {name}</p>    }});

3 直接使用函数调用

var Hello = React.createClass({     //注意,首字母必须大写,否则会jsx当作html自带元素    getName: function(){        if(this.props.name)            return this.props.name        else            return "world";    }    render: function(){        return <p>Hello {this.getName()}</p>    }});

4 或运算符

var Hello = React.createClass({     //注意,首字母必须大写,否则会jsx当作html自带元素    render: function(){        return <p>Hello {this.props.name || "World"}</p>    }});

万能的函数表达式

var Hello = React.createClass({     //注意,首字母必须大写,否则会jsx当作html自带元素    render: function(){        return <p>Hello {            (function(obj){                if(obj.props.name)                    return obj.props.name                else                    return "World"            })(this)        }</p>    }});

jsx语法实例

非dom属性介绍

为什么要有非DOM属性

dangerouslySetInnerHTML、ref、keydangerouslySetInnerHTML:在JSX中直接插入HTML代码ref:父组建引用子组建key:提高渲染性能

react diff算法流程图

react diff
key标识每个节点
启示:类似的节点写成一个的组件
使用类似列表展示元素时元素尽量加上唯一的key,不同组件之间的key可以一样

如何使用非DOM属性

<script src="./react.js"></script><script src="./JSXTransformer.js"></script><script type="text/jsx">    var Hello = React.createClass({     //注意,首字母必须大写,否则会jsx当作html自带元素        render: function(){            return <p>Hello World</p>        }    });    var style ={        color:'red',        border:'1px #000 solid'    };    var rawHTML = {        __html: "<h1>I'm inner HTML</h1>"    };    React.render(<div style={style} dangerouslySetInnerHTML={rawHTML}></div>/*<div>这里不能有文字?</div>*/,document.body);</script>

如何使用ref

<script src="./react.js"></script>    <script src="./JSXTransformer.js"></script>    <script type="text/jsx">        var Hello = React.createClass({     //注意,首字母必须大写,否则会jsx当作html自带元素        this.refs.childp.text        //不是真正的DOM节点(不能进行操作),而是react展示的DOM            render: function(){                return <p ref="childp">Hello World</p>            }        });        var style ={            color:'red',            border:'1px #000 solid'        };        var rawHTML = {            __html: "<h1>I'm inner HTML</h1>"        };        React.render(<div style={style} dangerouslySetInnerHTML={rawHTML}></div>/*<div>这里不能有文字?</div>*/,document.body);    </script>

key

<script src="./react.js"></script><script src="./JSXTransformer.js"></script><script src="./react.js"></script><script src="./JSXTransformer.js"></script><script type="text/jsx">    var Hello = React.createClass({     //注意,首字母必须大写,否则会jsx当作html自带元素    //this.refs.childp.text        //不是真正的DOM节点(不能进行操作),而是react展示的DOM        render: function(){            return <ul>            <li key="1">1</li>      //注意key="1",需要双引号            <li key="2">2</li>            <li key="3">3</li>            </ul>        }    });    var style ={        color:'red',        border:'1px #000 solid'    };    var rawHTML = {        __html: "<h1>I'm inner HTML</h1>"    };    React.render(<div style={style}><Hello></Hello></div>,document.body);</script>

jsx解释器架构介绍

阅读源代码

从执行顺序入手适当忽略细节重视烂笔头反复阅读

理解解释器架构

jiagou

组件生命周期详解

什么是生命周期

组件的生命周期

组件本质上是状态机,输入确定,输出一定确定。状态发生转换时会出发不同的钩子函数,从而让开发者有机会做出响应可以用事件的思路来理解状态

zujian

不同生命周期内可以自定义的函数

初始化

钩子函数
getDefaultProps //获取实例的默认属性组件的第一个实例装载之后才调用,第二个实例开始并不调用
getInitialState //获取实例的初始化状态
componentWillMount //组件即将被渲染到页面上
render //生成虚拟dom节点,由react渲染成真正的DOM节点
componentDidMount //组件真正装载之后调用,组件已经被渲染到了页面

运行中

componentWillReceivProps    //组件可能要接收到属性shouldComponentUpdate       //组件接收到新属性,返回false则不会调用render函数(diff 算法)componentWillUpdate         //在render调用之前调用render                      //组件真正装载之后调用,组件已经被渲染到了页面componentDidUpdate          //react渲染成真正的DOM节点之后调用

销毁

componentWillUnmount        //销毁操作之前调用

初始化阶段介绍

getDefaultProps

只调用一次,实例之间共享引用

getInitialState

初始化每个实例特有的状态

componentWillMount

render之前最后一次修改状态的机会

render

只能访问this.props和this.state,只有一个顶层组件,不允许修改状态和DOM输出

componentDidMount

成功render并渲染完成真实DOM之后触发,可以修改DOM

demo

调用顺序:

<script type="text/jsx">    var Hello = React.createClass({     //注意,首字母必须大写,否则会jsx当作html自带元素    //this.refs.childp.text        //不是真正的DOM节点(不能进行操作),而是react展示的DOM        getDefaultProps:function(){            console.log('getDefaultProps,1');            return null;        },        getInitialState: function(){            console.log('getInitialState,2');            return null;        },        componentWillMount: function(){            console.log('componentWillMount,3');        },        render: function(){            console.log('render,4');            return <ul>            <li key="1">1</li>             <li key="2">2</li>            <li key="3">3</li>            </ul>        },        componentDidMount:function(){            console.log('componentDidMount,5');        }    });    var style ={        color:'red',        border:'1px #000 solid'    };    var rawHTML = {        __html: "<h1>I'm inner HTML</h1>"    };    React.render(<div style={style}><Hello></Hello></div>,document.body);</script>    

各函数用法:

<script type="text/jsx">    var Hello = React.createClass({     //注意,首字母必须大写,否则会jsx当作html自带元素    //this.refs.childp.text        //不是真正的DOM节点(不能进行操作),而是react展示的DOM        getDefaultProps:function(){            console.log('getDefaultProps,1');            return {name:'Ray'};        },        getInitialState: function(){            console.log('getInitialState,2');            return {count:count++,                    ready:false            };        },        componentWillMount: function(){            console.log('componentWillMount,3');            this.setState({ready:true});        },        render: function(){            console.log('render,4');            return <p>Hello {this.props.name?this.props.name:"World"}<br/>{this.state.ready + " "} {this.state.count}</p>        },        componentDidMount:function(){            console.log('componentDidMount,5');            React.findDOMNode(this).innerText += ' well';        }    });    var style ={        color:'red',        border:'1px #000 solid'    };    var count = 0;    React.render(<div style={style}><Hello></Hello><br/><Hello></Hello><br/><Hello></Hello><br/><Hello></Hello><br/><Hello></Hello></div>,document.body);</script>

运行中阶段介绍

componentWillReceiveProps

父组件修改属性触发,可以修改新属性、修改状态

shouldComponentUpdate

返回false会阻止render调用

componentWillUpdate

不能修改属性和状态

render

只能访问this.props和this.state,只有一个顶层组件,不允许修改状态和DOM输出

componentDidUpdate

可以修改DOM

demo

<script src="./react.js"></script><script src="./JSXTransformer.js"></script><script src="./jquery-3.1.1.min.js"></script><script type="text/jsx">$(document).ready(    function(){        var Hello = React.createClass({     //注意,首字母必须大写,否则会jsx当作html自带元素        //this.refs.childp.text        //不是真正的DOM节点(不能进行操作),而是react展示的DOM            componentWillReceiveProps:function(newProps){                // to do...                console.log('componentWillReceiveProps,1');                console.log(newProps);            },            shouldComponentUpdate: function(){                console.log('shouldComponentUpdate,2');                return true;    //true表示组建需要更新,必须返回一个值,如果返回false,则下面的几个方法不会调用                //这个方法一般不用            },            componentWillUpdate: function(){                // to do...                console.log('componentWillUpdate,3');                //这个方法一般也不用            },            render: function(){                console.log('render,4');                return <p>Hello {this.props.name?this.props.name:"World"}<br/></p>            },            componentDidUpdate:function(){                //  to do...                    console.log('componentDidUpdate,5');                $(React.findDOMNode(this)).append("suprise!");                         }        });        var World = React.createClass({            getInitialState:function(){                return {name:''};            },            handleChange:function(event){                this.setState({name:event.target.value});            },            render:function(){                return <div>                    <Hello name={this.state.name}></Hello>                    <br/>                    <input type="text" onChange={this.handleChange} />                </div>            }        });        var style ={            color:'red',            border:'1px #000 solid'        };        var count = 0;        React.render(<div style={style}><World></World></div>,document.body);    });</script>

销毁阶段介绍

componentWillUmount

在删除组件之前进行清理操作,比如计时器和事件监听

demo

<script src="./react.js"></script><script src="./JSXTransformer.js"></script><script src="./jquery-3.1.1.min.js"></script><script type="text/jsx">$(document).ready(    function(){        var Hello = React.createClass({     //注意,首字母必须大写,否则会jsx当作html自带元素        //this.refs.childp.text        //不是真正的DOM节点(不能进行操作),而是react展示的DOM            componentWillReceiveProps:function(newProps){                // to do...                console.log('componentWillReceiveProps,1');                console.log(newProps);            },            shouldComponentUpdate: function(){                console.log('shouldComponentUpdate,2');                return true;    //true表示组建需要更新,必须返回一个值,如果返回false,则下面的几个方法不会调用                //这个方法一般不用            },            componentWillUpdate: function(){                // to do...                console.log('componentWillUpdate,3');                //这个方法一般也不用            },            render: function(){                console.log('render,4');                return <p>Hello {this.props.name?this.props.name:"World"}<br/></p>            },            componentDidUpdate:function(){                //  to do...                    console.log('componentDidUpdate,5');                $(React.findDOMNode(this)).append("suprise!");                         },            componentWillUnmount:function(){                console.log("BOOOOOOOOOOOOOOOOOOOM!");            }        });        var World = React.createClass({            getInitialState:function(){                return {name:''};            },            handleChange:function(event){                if(event.target.value == '321'){                React.unmountComponentAtNode(document.getElementsByTagName("body")[0]);                return;//没有return会继续调用render                }                //way 2:使用React.unmountComponentAtNode显式调用                this.setState({name:event.target.value});            },            render:function(){                if(this.state.name == '123'){                    return <div>123</div>                }                //way 1:在render中直接返回性的div                return <div>                    <Hello name={this.state.name}></Hello>                    <br/>                    <input type="text" onChange={this.handleChange} />                </div>            }        });        var style ={            color:'red',            border:'1px #000 solid'        };        var count = 0;        React.render(<div style={style}><World></World></div>,document.body);    });
0 0