React.PureComponent()
如果一个组件不需要我们自己写shouldComponentUpdate钩子函数,仅仅只是一个纯组件的话,最好使用PureComponent ,可以减少不必要的 render操作的次数,从而提高性能。
原理
shouldComponentUpdate钩子函数,在组件被渲染之前执行。
在组件的生命周期中,有一个shouldComponentUpdate方法,它的默认返回值是true。也就是说,不管props或者state有没有改变都会重新渲染组件。如果创建PureComponent
组件的话会有一个默认的shouldComponentUpdate(比较,当state或者props任意一个变了才重新渲染,否则不渲染)。
import React from 'react';
class Resources extends React.Component{} 改为=>
class Resources extends React.PureComponent{}
注意之处
1、浅比较
PureComponent
使用的是浅比较,如果你知道深拷贝和浅拷贝的区别,这里不难区分。如果数据是一个引用类型的数组或者对象,如果只是对原数据其进行添加删除等操作是不会重新渲染的,只有改变了数据的指向才会冲新渲染,就像reducer中需要重新返回一个新数据一样。
export default class List extends Component{
render(){
const list = this.props.list;
return (
<ul>
{
list.map((item, index) => {
return (
<li key={index}>
{item}
</li>
)
})
}
</ul>
)
}
}
class App extends Component {
state = {
arr: [1,2,3]
}
click(){
const arr = this.state.arr;
arr.push(5);
console.log(arr);
this.setState({arr});
}
render() {
return (
<div className="App">
<List list={this.state.arr} />
<button onClick={this.click.bind(this)}>点击变化了吗?</button>
</div>
);
}
}
以上代码,如果使用Component
生成组件,点击按钮时组件会重新渲染。如果使用PureComponent
的话,是不会重新渲染的,因为click事件中操作的还是原来的arr,浅比较认为state并未改变。
如果想要重新渲染的话,将click事件稍作修改就可以了(重新生成一个新的对象)
click(){
const arr = [...this.state.arr];
arr.push(5);
this.setState({arr});
}
服务端渲染
SSR
SSR是Server Slide Rendering
的缩写,即服务端渲染的意思。那么什么事服务端渲染呢?之前我们的项目都是客户端渲染:
![](https://img.haomeiwen.com/i3473978/c0a9e57d19209662.png)
如果是服务端渲染(准确的说应该是同构渲染):
![](https://img.haomeiwen.com/i3473978/9566ea8408891598.png)
服务端渲染的只是可视的一部分,为了确保组件的生命周期和事件处理,客户端需要再次进行渲染,但是二次渲染开销小的多。
服务端渲染的优势
-
服务端做初始渲染,因为服务端是内网请求,所以响应速度会很快。
-
解决了客户端等待渲染过程中出现的白屏现象。
-
解决单页应用的SEO,单页应用大部分主要HTML并不是由服务器返回的,而是脚本生成的。搜索引擎无法抓取页面相关内容。
React实现服务端渲染
随便找了一段代码,大致就是这个思路,实际项目中根据自己的需求去扩展。
import express from 'express';
import fs from 'fs';
import path from 'path';
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import Hello from './Hello.js';
function handleRender(req, res) {
// 把 Hello 组件渲染成 HTML 字符串
const html = ReactDOMServer.renderToString(<Hello />);
// 加载 index.html 的内容
fs.readFile('./index.html', 'utf8', function (err, data) {
if (err) throw err;
// 把渲染后的 React HTML 插入到 div 中
const document = data.replace(/<div id="app"><\/div>/, `<div id="app">${html}</div>`);
// 把响应传回给客户端
res.send(document);
});
}
const app = express();
// 服务器使用 static 中间件构建 build 路径
app.use('/build', express.static(path.join(__dirname, 'build')));
// 使用我们的 handleRender 中间件处理服务端请求
app.get('*', handleRender);
// 启动服务器
app.listen(3000);
...待补充
网友评论