即使状态/属性没有变化,PureComponent也会保持渲染

时间:2019-04-15 21:11:16

标签: reactjs react-redux react-component

我正在尝试学习和测试React.PureComponent,即使该纯组件的状态没有变化,它也会保持渲染。

我的PureComponent非常简单,它只通过connect接受一个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);

在上面的代码中,您可以看到,组件中没有任何状态。它仅接受来自props的动作函数作为connect。但是,每当我单击Reset Data按钮时,它都会不断调用render方法,如屏幕截图所示。

enter image description here

在屏幕截图中,我可以看到,每当我单击一个按钮时,全局状态存储都已更改。但是,该状态未在我的PureComponent中使用,它应该超出范围,并且我的组件应忽略以重新呈现。

每次更改全局状态存储时,都会创建

或Redux Action函数。并作为新对象传递给我的PureComponent吗?

从理论上讲,我不需要编写自己的shouldComponentUpdate函数,对吗?我很困惑,您能帮我了解一下这种行为吗?

我的目标是我不希望用户单击按钮时再次渲染PureComponent。

更新

我根据此article尝试了以下操作,但仍在重新渲染

const mapDispatchToProps = {
    resetWorkouts
};

2 个答案:

答案 0 :(得分:2)

这是因为react在prevProps和nextProps之间进行了比较浅的比较, 并且您可以控制仅在shouldComponentUpdate中,react不知道调度程序与先前渲染中的调度程序相同,因为您正在mapDispatchToProps函数内部使用return。 在您的组件和您的情况下,虽然功能将保持不变,但是您可以采用两种路径:

路径1:

覆盖shouldComponentUpdate生命周期挂钩,如下所示:

shouldComponentUpdate(){
return false;
}

路径2:

摆脱mapDispatchToProps内部的收益,简化concont,使其如下所示:

`conncect(state => ({}), {
        resetWorkouts: resetWorkouts})(YourComponent);`

使用上述路径之一应该会让您感觉很好

答案 1 :(得分:1)

渲染组件的原因是因为每次执行以下函数:

const mapDispatchToProps = dispatch => {
    return {
        resetWorkouts: () => dispatch(resetWorkouts())
    }
}

您的组件将收到名为resetWorkouts的属性的新实例(因为您正在创建内联数组函数)。您可以查看ownProps来检查您的组件是否已经有resetWorkouts

const mapDispatchToProps = (dispatch, ownProps) => {
    return {
        resetWorkouts: ownProps.resetWorkouts || () => dispatch(resetWorkouts())
    }
}