即使没有 state/prop 更改,PureComponent 仍会继续渲染
PureComponent keeps rendering even though no state/prop changes
我正在尝试学习和测试 React.PureComponent,即使该纯组件的状态没有变化,它也会继续呈现。
我的 PureComponent 非常简单,它通过 connect
hoc
只接受一个 Redux Action 函数
import React from 'react';
import {
Container,
Button
} from 'reactstrap'
import { connect } from 'react-redux'
import { resetWorkouts } from '../actions/workoutApiActions'
class About extends React.PureComponent {
render () {
const { resetWorkouts } = this.props;
console.log('in about render...')
return (
<React.Fragment>
<Container>
<h2>Api Data Reset</h2>
<Button color="danger" onClick={resetWorkouts}>Reset Data</Button>
</Container>
</React.Fragment>
);
}
}
const mapDispatchToProps = dispatch => {
return {
resetWorkouts: () => dispatch(resetWorkouts())
}
}
export default connect(null, mapDispatchToProps)(About);
在上面的代码中,您可以看到,组件中没有状态。它只接受 connect
中的 props
作为动作函数。但是,每当我单击 Reset Data
按钮时,它都会继续调用 render
方法,如屏幕截图所示。
在屏幕截图中,我可以看到,每当我单击一个按钮时,全局状态存储就会发生变化。但是,我的 PureComponent 中没有使用该状态,它应该超出范围,我的组件应该忽略重新渲染。
或者每次更改全局状态存储时都会创建 Redux Action 函数。 作为新对象传递给了我的 PureComponent ?
理论上,我不需要自己写shouldComponentUpdate
函数,对吧?我很困惑,你能帮我理解这种行为吗?
我的目标是我不希望我的 PureComponent 在用户单击按钮时再次呈现。
更新:
我已经根据这个article尝试了如下,但它仍在重新渲染
const mapDispatchToProps = {
resetWorkouts
};
这是因为 React 在 prevProps 和 nextProps 之间做了浅层比较,
并且您可以控制仅在 shouldComponentUpdate
中,react 不知道调度程序与之前渲染的调度程序相同,因为您在 mapDispatchToProps
函数中使用 return。
在您的组件和您的情况下,虽然功能将保持不变,但您可以采用两条路径:
路径 1:
覆盖shouldComponentUpdate
生命周期钩子,如下:
shouldComponentUpdate(){
return false;
}
路径 2:
去掉mapDispatchToProps
里面的return,简化connect,如下:
`conncect(state => ({}), {
resetWorkouts: resetWorkouts})(YourComponent);`
使用上述路径之一应该会让你顺利进行
你的组件渲染的原因是每次执行以下函数时:
const mapDispatchToProps = dispatch => {
return {
resetWorkouts: () => dispatch(resetWorkouts())
}
}
您的组件收到一个名为 resetWorkouts
的 属性 的新实例(因为您正在创建一个内联数组函数)。您可以查看 ownProps
以检查您的组件是否已经具有 resetWorkouts
:
const mapDispatchToProps = (dispatch, ownProps) => {
return {
resetWorkouts: ownProps.resetWorkouts || () => dispatch(resetWorkouts())
}
}
我正在尝试学习和测试 React.PureComponent,即使该纯组件的状态没有变化,它也会继续呈现。
我的 PureComponent 非常简单,它通过 connect
hoc
import React from 'react';
import {
Container,
Button
} from 'reactstrap'
import { connect } from 'react-redux'
import { resetWorkouts } from '../actions/workoutApiActions'
class About extends React.PureComponent {
render () {
const { resetWorkouts } = this.props;
console.log('in about render...')
return (
<React.Fragment>
<Container>
<h2>Api Data Reset</h2>
<Button color="danger" onClick={resetWorkouts}>Reset Data</Button>
</Container>
</React.Fragment>
);
}
}
const mapDispatchToProps = dispatch => {
return {
resetWorkouts: () => dispatch(resetWorkouts())
}
}
export default connect(null, mapDispatchToProps)(About);
在上面的代码中,您可以看到,组件中没有状态。它只接受 connect
中的 props
作为动作函数。但是,每当我单击 Reset Data
按钮时,它都会继续调用 render
方法,如屏幕截图所示。
在屏幕截图中,我可以看到,每当我单击一个按钮时,全局状态存储就会发生变化。但是,我的 PureComponent 中没有使用该状态,它应该超出范围,我的组件应该忽略重新渲染。
或者每次更改全局状态存储时都会创建 Redux Action 函数。 作为新对象传递给了我的 PureComponent ?
理论上,我不需要自己写shouldComponentUpdate
函数,对吧?我很困惑,你能帮我理解这种行为吗?
我的目标是我不希望我的 PureComponent 在用户单击按钮时再次呈现。
更新:
我已经根据这个article尝试了如下,但它仍在重新渲染
const mapDispatchToProps = {
resetWorkouts
};
这是因为 React 在 prevProps 和 nextProps 之间做了浅层比较,
并且您可以控制仅在 shouldComponentUpdate
中,react 不知道调度程序与之前渲染的调度程序相同,因为您在 mapDispatchToProps
函数中使用 return。
在您的组件和您的情况下,虽然功能将保持不变,但您可以采用两条路径:
路径 1:
覆盖shouldComponentUpdate
生命周期钩子,如下:
shouldComponentUpdate(){
return false;
}
路径 2:
去掉mapDispatchToProps
里面的return,简化connect,如下:
`conncect(state => ({}), {
resetWorkouts: resetWorkouts})(YourComponent);`
使用上述路径之一应该会让你顺利进行
你的组件渲染的原因是每次执行以下函数时:
const mapDispatchToProps = dispatch => {
return {
resetWorkouts: () => dispatch(resetWorkouts())
}
}
您的组件收到一个名为 resetWorkouts
的 属性 的新实例(因为您正在创建一个内联数组函数)。您可以查看 ownProps
以检查您的组件是否已经具有 resetWorkouts
:
const mapDispatchToProps = (dispatch, ownProps) => {
return {
resetWorkouts: ownProps.resetWorkouts || () => dispatch(resetWorkouts())
}
}