React是Facebook于2013年开源的框架。React解决的是前端MVC框架中的View视图层的问题。
DOM(文档对象模型Document Object Model)
将网页内所有内容映射到一棵树型结构的层级对象模型上,浏览器提供对DOM的支持,用户可以是用脚本调用DOM API来动态的修改DOM结点,从而达到修改网页的目的,
这种修改是浏览器中完成,浏览器会根据DOM的改变重绘改变的DOM结点部分。
修改DOM重新渲染代价太高,前端框架为了提高效率,尽量减少DOM的重绘,提出了Virtual DOM,所有的修改都是现在VirtualDOM上完成的,通过比较算法,
找出浏览器DOM之间的差异,使用这个差异操作D0M,浏览器只需要渲染这部分变化就行了。
React实现了DOM Diff算法可以高效比对Virtual DOM和DOM的差异。
Virtual DOM实际上就是内存中的一个数据结构、对象,本身不属于浏览器,而是在浏览器中通过js引擎构建出来的一个对象。不管怎么样,都是在浏览器中跑得东西,和服务器端没什么关系。
前后端,一般前后端指的是web的前后端,前端往往指的是浏览器,后端指的是wsgi、server这些东西
前端技术,通常指浏览器中能够跑的东西:CSS,HTML,JS
JSX是一种JavaScript和XML混写的语法,是JavaScript的扩展。
React.render(
content
,
document.getElementById('example')
)
替换src/index.js
程序
// 基于React框架,使用JSX语法,替换上述代码
// 1、导入react模块
import React from "react"; // 导入react模块
import ReactDOM from "react-dom"; // 导入react的DOM模块
// 2、创建React元素
class Root extends React.Component{ // 组件类定义,从React.Component类上继承,这个类生成JSXElement对象,即React元素
state = {
p1: "www.baidu.",
p2: "com"
} // 每一个react组件component都有一个状态变量state,它是一个js对象,可以定义属性来保存值。如果状态发生变化,会触发UI重新渲染。state是组件内部的私有属性
render(){ // 渲染函数,返回组件中渲染的内容, 注意,只能返回唯一一个顶级元素回去
console.log("render log");
setTimeout(() => this.setState({p2: "net"}), 3000); // 延时函数:设置异步修改状态 // state的变化,会触发调用render,所以,render内最好不要对state进行任何改变,虽然可以,但是尽量不要。
// this.state.p2 = "net"
return {this.state.p1 + this.state.p2}; // div是一个容器,可以包含其他html标记。这里只能包含一个顶级元素
}
}
// 3、将React元素添加到DOM的Element元素中并渲染
ReactDOM.render( , document.getElementById('root')); // 渲染,将组件类挂载到DOM树中要被渲染的元素中去。第一个参数是JSXElement对象;第二个参数是DOM的Element元素。指定DOM树中被渲染的元素id,将React元素对DOM树中的元素进行替换并重新渲染。
// 4、保存后文件自动编译
1、Top-level element 【顶级元素】: { html, body, frameset }。包括html, body, frameset, 表现如Block-level element, 属于高级块级元素.
2、Block-level element 【块级元素】: { p, h1~h6, div, ul }。顾名思义就是以块显示的元素,高度宽度都是可以设置的。比如我们常用的 p, h1~h6, div, ul 默认状态下都是属于块级元素。块级元素比较霸道,默认状态下每次都占据一整个行,后面的内容也必须再新起一行显示。当然非块级元素也可以通过css的 display:block;将其更改成块级元素。此外还有个特殊的,float也具有此功能。块级元素能够独立存在, 一般的块级元素之间以换行(如一个段落结束后另起一行)分隔。块级元素是构成一个html的主要和关键元素, 而任意一个块级元素均可以用Box model来解释说明.
3、Inline element 【内联元素】: { a, br, em, img, li, span }通俗点来说就是文本的显示方式,与块级元素相反,内联元素的高度宽度是不可以设置的,其宽度就是自身文字或者图片的宽度。我们常用到的、、
都属于内联元素。内联元素的显示特点就是像文本一样的显示,不会独自占据一个行。 当然内联元素也能变成块级元素,那就是通过css的display:inline;和float来实现。内联元素依附其他块级元素存在, 紧接于被联元素之间显示, 而不换行.
注意:
1、React组件的render函数return,只能是一个顶级元素。组件是最小封装对象
2、JSX语法是XML,要求所有元素闭合,注意
不能写成
首字母小写就是html标记,首字母大写就是组件。 每一个react组件component都有一个状态变量state,它是一个js对象,可以定义属性来保存值。 将本目录中’./test.html’使用jsx进行替换。 props,使得可以从外部给React组件传递数据。传入的这个数据如果是对象,还可以访问、修改对象的属性。 总结: ES6使用构造器,为组件添加属性 组件的声明周期可分为三个状态: 组件的生命周期状态,说明在不同时机访问组件,组件正处在生命周期的不同状态上。在不同的声明周期状态访问,就产生不同的方法。 生命周期的方法如下: 装载组件触发 更新组件触发。这些方法不会在首次render组件的周期调用 可以在你确认不需要更新组件时使用。 卸载组件触发 从上图可以看出: 从React15.0开始,支持无状态组件。定义为: 无状态组件也叫函数式组件。 改写定义代码为: react中,虚拟dom有可能会被文档。组件的state、props、生命周期一般都会被问,需要理解。
要求严格的HTML标记,要求所有标签都必须闭合。br也应写成
,/前留一个空格。
单行省略小括号,多行请使用小括号
元素有嵌套,建议多行,注意缩进
JSX表达式:使用{}扩起来,如果大括号内使用了引号,会当做字符串处理。例如:
3.5 组件状态state*
如果状态发生变化,会触发UI重新渲染。
state是组件内部的私有属性。class Root extends React.Component{ // 组件类定义,从React.Component类上继承,这个类生成JSXElement对象,即React元素
state = {
p1: "www.baidu.",
p2: "com"
} // 每一个react组件component都有一个状态变量state,它是一个js对象,可以定义属性来保存值。如果状态发生变化,会触发UI重新渲染。state是组件内部的私有属性
render(){ // 渲染函数,返回组件中渲染的内容
console.log("render log");
// this.setState({p2: "net"}); // 不可以对还在更新中的state使用setState
setTimeout(() => this.setState({p2: "net"}), 3000); // 延时函数:设置异步修改状态,和上一行是两码事。
// this.state.p2 = "net"
return
3.6 复杂状态
可以将’./test.html’文件移动到上一层目录下,然后在浏览器中http://localhost:3000/test.html
进行访问查看效果。class SubElement extends React.Component{
render(){
return
3.7 props属性*
props的属性是只读的,不允许修改。import React from "react";
import ReactDOM from "react-dom";
class SubElement extends React.Component{
render(){
console.log(this.props.name)
console.log(this.props.parent, 'SubElement.props.parent.state.flag=' + this.props.parent.state.flag) // 还可以通过props传递的对象,修改、访问外层对象的元素
return
name="我是subElement"
,这个属性作为单一对象传递给组件,加入到组件的props属性中;parent={this}
,这里的this是Trigger组件本身。3.8 构造器constructor
import React from "react";
import ReactDOM from "react-dom";
class Trigger extends React.Component{
// state = {flag: true}
constructor(props){ /*ES6使用构造器,为组件添加属性。通过构造器添加属性,使代码可读性更好*/
super(props); // 调用父类的constructor,需传入props属性。
this.state = {flag: true}
}
handlerClick(event){
alert("触发事件的ID为" + event.target.id)
this.setState({flag: !this.state.flag})
}
render(){
return (
3.9 组件的生命周期管理*
componentWillMount
在渲染前调用,在客户端也在服务端。只会在装载之前调用一次。componentDidMount
:在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()
来进行访问。如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout,setInterval
或者发送AJAX请求等操作(防止异部操作阻塞U1)。只在装载完成后调用一次,在render之后。
componentWillReceiveProps(nextProps)
在组件接收到一个新的prop时被调用。这个方法在初始化render时不会被调用。shouldComponentUpdate(nextProps,nextState)
返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。
如果设置为false,就是不允许更新组件,那么componentWillUpdate、componentDidUpdate
不会执行。componentWillUpdate(nextProps, nextState)
在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。componentDidUpdate(prevProps,prevState)
在组件完成更新后立即调用。在初始化时不会被调用。
componentWillUnmount
在组件从DOM中移除的时候立刻被调用。
constructor
构造器是最早被执行的函数更新声明周期函数
,需要更新state
或props
。
3.10 无状态组件*
import React from "react"; // 导入react模块
import ReactDOM from "react-dom"; // 导入react的DOM模块
function Root(props){
return
开发中很多情况下,组件其实很简单,不需要state状态,也不需要使用生命周期函数。无状态组件很好的满足了需求。
props
,返回一个React元素。import React from "react"; // 导入react模块
import ReactDOM from "react-dom"; // 导入react的DOM模块
let ROOT = props =>
总结