1、shouldComponentUpdate钩子:
为什么使用该钩子?
场景一:父组件重新render(),必然导致子组件重新render。有可能子组件并没有任何更新。
场景二:子组件调用setState({}),很明显虽然调用了更新state方法,但没有发生实质性更新。这种情况下并不需要重新Render子组件。
2、什么是PureComponent
React.PureComponent与React.Component完全相同,只是它为你处理了shouldComponentUpdate()方法。当属性或状态发生变化时,PureComponent 将对属性和状态进行浅比较。什么是浅比较,看下面代码。
手动实现pure component:
import React from 'react';
import PropTypes from 'prop-types';
/*
* React.PureComponent
*/
//=>把两个对象进行浅比较
// 只比较对象的第一级
// 如果属性值是基本类型的,我们只需要比较值是否一样即可
function shallowEqual(obj1, obj2) {
if (Object.keys(obj1).length !== Object.keys(obj2).length) {
return false;
}
for (let key in obj1) {
if (obj1[key] !== obj2[key]) {
return false;
}
}
return true;
}
class CountShow extends React.Component {
render() {
return <div>
{this.props.num}
</div>;
}
}
export default class Count extends React.Component {
state = {
num: 0,
x: 100,
arr: [10, 20]
};
render() {
console.log('OK');
return <>
<CountShow num={this.state.num} />
<button onClick={ev => {
this.state.arr.push(30);
this.setState({
arr: [...this.state.arr]
});
}}>累加</button>
</>;
}
shouldComponentUpdate(nextProps, nextState) {
return !shallowEqual(this.state, nextState) || !shallowEqual(this.props, nextProps);
}
}
3、纯函数是什么
1、入参不能被改变,下面这个例子item作为入参,被改变了,因此不纯。
var values = { a: 1 };
function impureFunction ( items ) {
var b = 1;
items.a = items.a * b + 2;
return items.a;
}
var c = impureFunction( values );
但是这种情况,就是纯函数
var values = { a: 1 };
function pureFunction ( a ) {
var b = 1;
a = a * b + 2;
return a;
}
var c = pureFunction( values.a );
// `values.a` 没有被改变, 它的值仍然是 1
2、不可依赖外部变量,以下例子依赖于外部变了b,因此不纯。
var values = { a: 1 };
var b = 1;
function impureFunction ( a ) {
a = a * b + 2;
return a;
}
var c = impureFunction( values.a );
// c 的值依赖于外部变量 b
3、不可修改外部变量。
let a = 1;
function func() {
a = 'b';
};
func();
console.log(a); // b
4、纯函数的好处是什么
- 更容易进行测试,结果只依赖输入,测试时可以确保输出稳定
- 更容易维护和重构,我们可以写出质量更高的代码
- 更容易调用,我们不用担心函数会有什么副作用
- 结果可以缓存,因为相同的输入总是会得到相同的输出
5、纯函数的定义
1. 如果函数的调用参数相同,则永远返回相同的结果。
2. 该函数不会产生任何可观察的副作用,例如网络请求,输入和输出设备或数据突变(mutation)。
4、 getDerivedStateFromProps() 方法
调用时机:render()之前,也就是重新渲染之前,包括首次render和以后的每次update。
作用:props改变导致组件重新render(),组件render()导致getDerivedStateFromProps()被调用。该函数一调用就可以通过props改变后的值,更新state。该函数的返回值就是新的state。一句话概括:props变了,我想修改state。
<div id="root"></div>
<script type="text/babel">
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritesite: "runoob"};
}
static getDerivedStateFromProps(props, state) {
return {favoritesite: props.favsite };
}
render() {
return (
<h1>我喜欢的网站是 {this.state.favoritesite}</h1>
);
}
}
ReactDOM.render(<Header favsite="Google"/>, document.getElementById('root'));
5、路由中的模糊匹配、exact是什么?
1、Route中的exact。
<Route path="/about" component={About} />
不加exact,只要匹配到/about,就会渲染About组件。例如当前url是/about/haha,该url包含了/about,因此会渲染about组件。
<Route exact path="/about" component={About} />
加了exact之后,必须当前url完全符合path,换句话说,当前路由是/about/haha时,不显示About组件。必须当前路由事/about才行。
2、NavLink中的exact。
<NavLink exact to="/admin" activeClassName="light">
About
</NavLink>
先解释一下activeClassName是什么。我们需要手动给该属性传入一个class名称,当该按钮处于活跃状态时,会给该按钮加上你先前指定的class。什么时候该按钮处于活跃状态,例如上面这段代码,如果当前地址栏也就是当前url是/admin时,那么该NavLink就会处于活跃状态,此时,该NavLink会自动添加一个class,class名字叫做light。
exact就是模糊匹配,如果不加exact,只要当前url包含/admin,该按钮就处于活跃状态。例如,当前url是
admin/haha,这种情况下该按钮也会处于活跃状态。特殊情况: 如果to为空的话,而且不开启exact模式,那么任何url都能匹配上to ,因此,to为空的按钮永远处于活跃状态。