SCU、PureComponent与memo
SCU:shouldComponentUpdate
- React默认:父组件有更新,子组件无条件更新!!
- 因此在不需要进行更新的子组件中,在SCU可对数据进行判断,对不需要进行更新的子组件返回false(改方法默认返回true);
- 此方法仅作为性能优化的方式而存在,且应该考虑使用React内置的 PureComponent组件,可先不使用SCU,有性能问题再考虑;
- 不建议在 shouldComponentUpdate() 中进行深层比较或使用 JSON.stringify()。这样非常影响效率,且会损害性能;
- 在SCU中一定要配合不可变值进行使用,例如在组件中对某一数据进行更改时,使用了push方法,那么当前的改数组的值与next数组的值则是相同的,那么就会导致即使数据有更改,但是在SCU中却判断不出来,导致问题出现;
- 用法如下:如果当前的props.text与nextProps.text不同的时候才会发生渲染;
shouldComponentUpdate(nextProps, nextState){
if (nextProps.text !== this.props.text){
return true;
}
return false;
}
PureComponent和memo
PureComponent
会对 props
和 state
进行浅层比较,并减少了跳过必要更新的可能性- 如果是在函数组件中,则使用
memo
- 使用如下;
Class App extends React.PureCOmponent{}
React.memo
为高阶组件。它与 React.PureComponent
非常相似,但只适用于函数组件,而不适用 class 组件;React.memo
默认情况下只对对象进行浅层比较,如果想要控制对比过程,那么请将自定义的比较函数通过第二个参数传入来实现;
function MyComponent(props){
}
function areEqual(prevProps, nextProps){
}
export default React.memo(MyComponent, areEqual);
关于组件公共逻辑的抽离
- mixin,已被React弃用
HOC
,高阶组件Render Props
高阶组件
- 高阶组件不是一种功能,而是一种模式
- redux connect是高阶组件
const HOCFactory = (Component) => {
class HOC extends React.Component{
render (){
return (
<Component {...this.props} />
)
}
}
return HOC;
}
const EnHancedComponent1 = HOCFactory(WrappedComponent1);
const EnHancedComponent2 = HOCFactory(WrappedComponent1);
- 如下实现一个高阶组件,将获取鼠标位置抽离成公共逻辑
import React from 'react';
const App = (props) => {
const {x, y} = props.mouse;
return (
<div style={{height:'500px'}}>
<h1>The mouse positon is ({x}, {y})</h1>
</div>
)
}
const withMouse = (Component) => {
class WithMouseComponent extends React.Component{
constructor(props){
super(props);
this.state = {
x:0,
y:0
}
}
handleMouseEvent = (event) => {
this.setState({
x: event.clientX,
y: event.clientY
})
}
componentDidMount(){
}
render (){
return (
<div style={{height:'500px'}} onMouseMove={this.handleMouseEvent}>
{}
<Component {...this.props} mouse={this.state} />
</div>
)
}
}
return WithMouseComponent
}
export default withMouse(App);
Render Props
- 核心思想:通过一个函数将class组件的state作为props传递给纯函数组件
import React from 'react';
import propTypes from 'prop-types';
const App = (props) => {
return (
<div style={{height:'500px'}}>
<Mouse render = { ({x, y}) => {
return (
<h1>The mouse positon is ({x}, {y})</h1>
)
}}></Mouse>
</div>
)
}
class Mouse extends React.Component{
constructor(props){
super(props);
this.state = {
x:0,
y:0
}
}
handleMouseEvent = (event) => {
this.setState({
x: event.clientX,
y: event.clientY
})
}
render (){
return (
<div style={{height:'500px'}} onMouseMove={this.handleMouseEvent}>
{}
{this.props.render(this.state)}
</div>
)
}
}
Mouse.propTypes = {
render: propTypes.func.isRequired
}
export default App;
HOC vs Render Props
- HOC:模式简单,但会增加组件层级
- Render Props:代码简洁,学习成本高
- 按需使用