reactjs学习手记(1)

本文详细介绍React框架的核心概念,包括React的开发背景、组件设计原则及其优势,并深入探讨JSX语法特性,组件生命周期管理等关键知识点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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>p
id  : #
    div#header+div.page
class:.

属性: []
    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、key
dangerouslySetInnerHTML:在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);
    }
);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值