首页 技术 正文
技术 2022年11月9日
0 收藏 505 点赞 2,304 浏览 11824 个字

<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px ‘PingFang SC’; color: #616161}
span.s1 {font: 21.0px ‘Helvetica Neue’}
–>

React 背景知识

  React 是一个用于构建用户界面的 JavaScript 库,主要用于构建 UI,而不是一个 MVC 框架,但可以使用 React 作为 MVC 架构的 View 层轻易的在已有项目中使用,它是一个用于构建用户界面的 JavaScript 库,起源于 Facebook 的内部项目,用来架设 Instagram 的网站,于 2013 年 5 月开源。React 拥有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和使用它。

<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px ‘PingFang SC’; color: #616161}
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px ‘PingFang SC’; color: #616161; min-height: 29.0px}
–>

  以前没有 ajax 技术的时候,web 页面从服务端整体渲染出 html 输出到浏览器端进行渲染,同样的,用户的一个改变页面的操作也会刷新整个页面来完成。直到有了 ajax 出现,实现页面局部刷新,带来的高效和分离让 web 开发者们惊叹不已。但随之而来的问题是,复杂的用户交互及展现需要通过大量的 DOM 操作来完成,这让页面的性能以及开发的效率又出现了新的瓶颈。

  时至今日,谈到前端性能优化,减少 DOM 元素、减少 reflow 和 repaint、编码过程中尽量减少 DOM 的查询等手段是大家耳熟能详的。而页面任何UI的变化都是通过整体刷新来完成的。幸运的是,React 通过自己实现的 DOM Diff 算法,计算出虚拟页面当前版本和新版本之间的差异,最小化重绘,避免不必要的 DOM 操作,解决了这两个公认的前端性能瓶颈,实现高效 DOM 渲染。

  我们知道,频繁的操作 DOM 所带来的性能消耗是很大的,而 React 之所以快,是因为它不直接操作 DOM,而是引进虚拟 DOM 的实现来解决这个问题

  对于页面的更新,React 通过自己实现的 DOM Diff 算法来进行差异对比、差异更新,反映到页面上就是只重绘了更新的部分,从而提高渲染效率。

备注:以下性能阐述参考自尤雨溪。

  对于 React 的性能方面,想啰嗦几句:

    1. React 从来没有说过 “React 比原生操作 DOM 快”。React 的基本思维模式是每次有变动就整个重新渲染整个应用。如果没有 Virtual DOM,简单来讲就是直接重置 innerHTML。

    2. 在比较性能的时候,要分清楚初始渲染、小量数据更新、大量数据更新这些不同的场合。

    3. 不要天真地以为 Virtual DOM 就是快,diff 不是免费的,Virtual DOM 真正的价值从来都不是性能,而是它

      1) 为函数式的 UI 编程方式打开了大门;

      2) 可以渲染到 DOM 以外的其他场景,如 backend、native。

组件化

  在业务开发中,遇到公共的模板部分,我们不得不将模板和规定的数据格式耦合在一起来实现组件。而在 React 中,我们可以使用 JSX 语法来封装组件,将组件的结构、数据逻辑甚至样式都聚合在一起,更加简单、明了、直观的定义组件。

  有了组件化的实现,我们可以很直观的将一个复杂的页面分割成若干个独立组件,再将这些独立组件组合完成一个复杂的页面。这样既减少了逻辑复杂度,又实现了代码的重用。

React 基础

模板

<!DOCTYPE html>

<html>

 <head>

<script src=“js/react.js”></script>

 <script src=“js/react-dom.js”></script>

 <script src=“js/browser.min.js”></script>

</head>

<body>

<div id=“example”></div>

<script type=“text/babel”>

/*

* ReactDOM.render 是 React 的最基本方法,用于将模板转为 HTML 语言,

 * 并插入指定的 DOM 节点。

 *
*/

ReactDOM.render(

<h1>Hello, 博看文思!</h1>,
document.getElementById(‘example’)

);

</script>

 </body>

</html>

<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px ‘PingFang SC Light’; color: #fffddf}
–>

JSX

  上一节的代码, HTML 语言直接写在 JavaScript 语言之中,不加任何引号,这就是 JSX 的语法,它允许 HTML 与 JavaScript 的混写

<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px ‘PingFang SC’; color: #b8b8b8}
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px ‘Helvetica Neue’; color: #b8b8b8}
p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px Menlo; color: #b8b8b8}
span.s1 {font: 21.0px ‘Helvetica Neue’}
span.s2 {font: 21.0px ‘PingFang SC’}
span.Apple-tab-span {white-space:pre}
–>

JSX的好处:

1.使用JSX语法来封装组件有什么好处:

  1)熟悉的代码

  2)更加语义化

  3)更加抽象且直观

2.几个注意点:

  1)render的方法中return的顶级元素只能是一个;

  2)如果要定义样式的时候,不能这样去写
    // 不要出现类似的错误,style=“opacity:{this.state.opacity};”

  3)使用 className 和 htmlFor 来替代对应的class 和 for

提示:关于组件化的话题,感兴趣的话可以继续关注Vuejs、Web components等对组件的写法。/**随着更为复杂的多端环境的出现,组件标准化还有着更大的想象空间,React的组件定义不是终点,也不一定是标准,但会在组件化的道路上留下深刻de影响。**/

JSX 基本语法:

    var names = [‘Alice’, ‘Emily’, ‘Kate’];


ReactDOM.render(

<div>

{

 names.map(function (name,key) {

return <div key={key}>Hello, {name}!</div>

})

}

</div>,

document.getElementById(‘example’)

);

<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px ‘Songti SC’; color: #b8b8b8}
span.s1 {font: 21.0px Georgia}
span.s2 {font: 21.0px Courier}
–>

  上面代码体现了 JSX 的基本语法规则:遇到 HTML 标签(以 < 开头),就用 HTML 规则解析;遇到代码块(以 { 开头),就用 JavaScript 规则解析。

<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px ‘Songti SC’; color: #b8b8b8}
span.s1 {font: 21.0px Georgia}
–>

  JSX 允许直接在模板插入 JavaScript 变量。如果这个变量是一个数组,则会展开这个数组的所有成员。

var arr = [

<h1>Hello world!</h1>,

<h2>React is awesome</h2>,

];

ReactDOM.render(

<div>{arr}</div>,

 document.getElementById(‘example’)

);

组件

1.概念

  React 允许将代码封装成组件(component),然后像插入普通 HTML 标签一样,在网页中插入这个组件。React.createClass 方法就用于生成一个组件类

2.代码示例

var HelloMessage = React.createClass({

render: function() {

return <h1>Hello {this.props.name}</h1>;

}

});


ReactDOM.render(

<HelloMessage name=“John” />,

document.getElementById(‘example’)

);
var HelloMessage = React.createClass({

 render: function() {

return <h1 className=“green”>Hello {this.props.name}</h1>;

 }

});


ReactDOM.render(

  <HelloMessage name=“John” />,

document.getElementById(‘example’)

);

<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px Georgia; color: #b8b8b8}
–>

this.props.children

this.props 对象的属性与组件的属性一一对应,但是有一个例外,就是 this.props.children 属性。它表示组件的所有子节点

<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px Menlo; color: #f9f9f9}
span.s1 {color: #fce239}
span.s2 {color: #ff7a00}
span.s3 {color: #bcbcbc}
span.s4 {font: 21.0px ‘PingFang SC’; color: #bcbcbc}
span.s5 {color: #a8a65a}
span.s6 {color: #70d34c}
–>

var NotesList = React.createClass({
render: function() {
return (
<ol>
{
/*
* 因为this.props.children的返回值会根据子节点的数量返回undefined,object,array.
* 所以react提供了一个react.Children的方法专门处理this.props.children
* */
React.Children.map(this.props.children, function (child) {
return <li>{child}</li>;
})
}
</ol>
);
}
});
ReactDOM.render(
<NotesList>
<span>hello</span>
<span>world</span>
</NotesList>,
document.getElementById(“example”)
);

 PropTypes

<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px ‘Songti SC’; color: #b8b8b8}
span.s1 {font: 21.0px Courier}
–>

组件的属性可以接受任意值,字符串、对象、函数等等都可以。有时,我们需要一种机制,验证别人使用组件时,提供的参数是否符合要求。组件类的PropTypes属性,就是用来验证组件实例的属性是否符合要求。

var MyTitle = React.createClass({
propTypes: {
/*
* 声明title属性是必须的,并且数据类型要为字符串,相当于是规范化的接口文档
* */
title: React.PropTypes.string.isRequired,
},
render: function() {
return <h1> {this.props.title} </h1>;
}
});
var data = “123”;
ReactDOM.render(
<MyTitle title={data} />,
document.getElementById(“example”)
);

   错误示范:

<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px Consolas; color: #000000}
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px Consolas; color: #999999; min-height: 25.0px}
p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px Consolas; color: #999999}
span.s1 {color: #0076aa}
span.s2 {color: #a67e59}
span.s3 {color: #991855}
span.s4 {color: #999999}
span.s5 {color: #101010}
–>

var data = 123;
ReactDOM.render(
<MyTitle title={data} />,
document.body
);

<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px Menlo; color: #f9f9f9}
–>

getDefaultProps

<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px ‘Songti SC’; color: #b8b8b8}
span.s1 {font: 21.0px Courier}
span.s2 {font: 21.0px Georgia}
–>

getDefaultProps 方法可以用来设置组件属性的默认值

<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px Menlo; color: #f9f9f9}
span.s1 {color: #fce239}
span.s2 {color: #ff7a00}
span.s3 {color: #a8a65a}
span.s4 {color: #70d34c}
span.s5 {color: #bcbcbc}
–>

var MyTitle = React.createClass({
getDefaultProps: function () {
return {
title:”hello world”
}
},
render: function() {
return <h1> {this.props.title} </h1>;
}
});
// var data = “123”;
ReactDOM.render(
<MyTitle />,
document.getElementById(“example”)
);

 获取真实的 DOM 节点

<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px ‘Songti SC’; color: #b8b8b8}
span.s1 {font: 21.0px Georgia}
span.s2 {text-decoration: underline}
–>

  组件并不是真实的 DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟 DOM (virtual DOM)。只有当它插入文档以后,才会变成真实的 DOM 。根据 React 的设计,所有的 DOM 变动,都先在虚拟 DOM 上发生,然后再将实际发生变动的部分,反映在真实 DOM上,这种算法叫做 DOM diff ,它可以极大提高网页的性能表现。

<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px Menlo; color: #f9f9f9}
span.s1 {color: #fce239}
span.s2 {color: #ff7a00}
span.s3 {color: #a8a65a}
span.s4 {color: #70d34c}
–>

var MyComponent = React.createClass({
handleClick: function() {
this.refs.myTextInput.focus();
},
render: function() {
return (
<div>
<input type=“text” ref=“myTextInput” />
<input type=“button” value=“Focus the text input” onClick={this.handleClick} />
</div>
);
}
});ReactDOM.render(
<MyComponent />,
document.getElementById(‘example’)
);

 this.state

  组件免不了要与用户互动,React 的一大创新,就是将组件看成是一个状态机,一开始有一个初始状态,然后用户互动,导致状态变化,从而触发重新渲染 UI。React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面

var LikeButton = React.createClass({
getInitialState: function() {
/*
* 设置状态的初始值
* */
return {liked: false};
},
handleClick: function() {
/*
* 更改状态
* */
this.setState({liked: !this.state.liked});
},
render: function() {
var text = this.state.liked ? ‘喜欢’ : ‘不喜欢’;
return (
<p onClick={this.handleClick}>
你 {text} 他. 点击切换.
</p>
);
}
});ReactDOM.render(
<LikeButton />,
document.getElementById(‘example’)
); 

<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px ‘Songti SC’; color: #b8b8b8}
span.s1 {font: 21.0px Georgia}
span.s2 {font: 21.0px Courier}
–>

  由于 this.props 和 this.state 都用于描述组件的特性,可能会产生混淆。一个简单的区分方法是,this.props 表示那些一旦定义,就不再改变的特性,而 this.state 是会随着用户互动而产生变化的特性。

var Input = React.createClass({
getInitialState: function() {
return {value: ‘Hello!’};
},
handleChange: function(event) {
this.setState({value: event.target.value});
},
render: function () {
var value = this.state.value;
return (
<div>
<input type=“text” value={value} onChange={this.handleChange} />
<p>{value}</p>
</div>
);
}
});ReactDOM.render(<Input/>, document.body);

组件 API

<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px ‘PingFang SC Light’; color: #fffddf}
–>

组件的7个方法:

  设置状态:setState;

  替换状态:replaceState;

  设置属性setProps;

  替换属性replaceProps;

  强制更新:forceUpdate;

  获取DOM节点:getDOMNode;

  判断组件挂载状态:isMounted。

组件生命周期

初始化

getDefaultProps:设置默认性的值

getInitialState:设置初始的状态

componentWillMount:(组件即将被装载)

render(渲染)

componentDidMount:组件已经被装载,只会在第一个组件被调用的时候出发

运行中

componentWillReceiveProps   在组件将要接收到属性的时候,接收属性前

shouldComponentUpdate    在接收到新的 props 或者 state,将要渲染之前调用。该方法在初始化渲染的时候不会调用

componentWillUpdate         render 触发之前,更新

render              渲染

componentWillUnmount      在组件从 DOM 中移除的时候立刻被调用

销毁

componentWillUnmount     在组件从 DOM 中移除的时候被立刻调用

var Hello = React.createClass({
getInitialState: function () {
return {
opacity: 1.0
};
}, componentDidMount: function () {
this.timer = setInterval(function () {
var opacity = this.state.opacity;
opacity -= .05;
if (opacity < 0.1){
opacity = 1.0;
}
this.setState({
opacity: opacity
});
}.bind(this), 100);
}, render: function () {
return (
<div style={{opacity: this.state.opacity}}>
Hello {this.props.name}
</div>
);
}
});ReactDOM.render(
<Hello name=“world”/>,
document.body
);

<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px ‘Songti SC’; color: #b8b8b8}
span.s1 {font: 21.0px Georgia}
span.s2 {text-decoration: underline}
span.s3 {font: 21.0px ‘Songti SC’; text-decoration: underline}
–>

因为 React 组件样式是一个对象第一重大括号表示这是 JavaScript 语法,第二重大括号表示样式对象

Ajax

<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px ‘Songti SC’; color: #b8b8b8}
span.s1 {font: 21.0px Georgia}
–>

  上面代码没有使用 jQuery 完成 Ajax 请求,这是为了便于说明。React 本身没有任何依赖,完全可以不用jQuery,而使用其他库。

<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px Menlo; color: #f9f9f9}
span.s1 {color: #fce239}
span.s2 {color: #ff7a00}
span.s3 {color: #a8a65a}
span.s4 {color: #75b1b1}
span.s5 {color: #70d34c}
span.s6 {color: #f9f9f9}
–>

var Input = React.createClass({
getInitialState: function () {
return {users:[]}
},
componentDidMount:function(){
var _this = this;
$.get(“http://localhost:8080/users?act=get”,function (data){
console.log(data);
_this.setState({
users:data
});
});
},
render: function () {
var users = this.state.users;
console.log(users);
return <table>
{
users.map(function (user,key){
return <tr key={key}><td>{user.firstName}</td><td>{user.lastName}</td></tr>
})
}
</table>
}
});
ReactDOM.render(<Input/>,document.getElementById(“test”));

<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px Menlo; color: #f9f9f9}
span.s1 {color: #fce239}
span.s2 {color: #ff7a00}
span.s3 {color: #a8a65a}
span.s4 {color: #70d34c}
span.s5 {color: #75b1b1}
–>
<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px Menlo; color: #f9f9f9}
span.s1 {color: #fce239}
span.s2 {color: #ff7a00}
span.s3 {color: #a8a65a}
span.s4 {color: #dff74c}
span.s5 {color: #75b1b1}
span.s6 {color: #70d34c}
–>

<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px Helvetica; color: #b8b8b8}
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px ‘PingFang SC’; color: #b8b8b8}
span.s1 {font: 21.0px ‘PingFang SC’}
span.s2 {font: 21.0px Helvetica}
–>
<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px ‘Songti SC’; color: #b8b8b8}
span.s1 {font: 21.0px Courier}
span.s2 {font: 21.0px Georgia}
–>
<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px Menlo; color: #f9f9f9}
span.s1 {color: #fce239}
span.s2 {color: #ff7a00}
span.s3 {color: #bcbcbc}
span.s4 {font: 21.0px ‘PingFang SC’; color: #bcbcbc}
span.s5 {font: 21.0px ‘PingFang SC’; color: #b8b8b8}
span.s6 {color: #70d34c}
span.s7 {color: #a8a65a}
–>
<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px ‘Songti SC’; color: #b8b8b8}
span.s1 {font: 21.0px Georgia}
–>
<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px Menlo; color: #f9f9f9}
span.s1 {color: #fce239}
span.s2 {color: #ff7a00}
span.s3 {color: #a8a65a}
span.s4 {color: #bcbcbc}
span.s5 {font: 21.0px ‘PingFang SC’; color: #bcbcbc}
span.s6 {color: #75b1b1}
span.s7 {color: #70d34c}
span.s8 {font: 21.0px ‘PingFang SC’; color: #70d34c}
span.s9 {font: 21.0px ‘PingFang SC’}
–>
<!–
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px ‘Songti SC’; color: #b8b8b8}
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px ‘PingFang SC’; color: #b8b8b8}
span.s1 {font: 21.0px Georgia}
span.s2 {font: 21.0px Helvetica}
–>

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,492
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,907
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,740
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,495
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,132
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,295