【问题标题】:React Redux mapStateToProps is re-renderingReact Redux mapStateToProps 正在重新渲染
【发布时间】:2018-12-12 21:48:33
【问题描述】:

我遇到了一个问题,我的组件正在重新渲染,但它不应该重新渲染(我总是发送相同的数据集)。后来我发现如果我的 mapStateToProps 看起来像这样:

function mapStateToProps({reducerContent},ownProps) {
    return {
        ...reducerContent
    }
}

它不会重新渲染(如果我发送相同的数据集)但这种形式的 mapStateToProps 将重新渲染我的组件:

function mapStateToProps({reducerContent},ownProps) {
    return {
        data: {
            ...reducerContent
        }
    }
}

您可以在下面找到我的减速器和组件。 reducer:(action.data 是浅对象):

const reducerContent = (state = {}, action) => {
    switch ( action.type ){
        case types.GET_CONTENT:
            return {
                ...state,
                ...action.data
            };

        default:
            return state;
    }
};

组件(将进一步开发):

import React, {Component}   from 'react';
import {connect}            from 'react-redux';

class Content extends Component {
    render() {
        return {this.props.content}
    }
}

function mapStateToProps({reducerContent},ownProps) {
    return {
        ...reducerContent
    }
}

export default connect(mapStateToProps,null)(Content)

【问题讨论】:

  • 它将重新渲染,因为您正在使用您的值定义一个新的 prop data
  • 好的,但它不应该在添加此道具后重新渲染(假设是第一次请求)并且没有对减速器数据进行任何更改,或者?
  • 你的两个不同的mapStateToProps 不等价。
  • componentShouldUpdate 将允许您制定一个规则,以便您可以在 data 上定义更好的相等性检查。否则,您将创建一个新对象并且只比较引用。
  • @Colin 是的,他们是(在控制台中检查并尝试返回静态数据)。

标签: javascript reactjs react-redux rerender


【解决方案1】:

connect 实现为PureComponent,即它对mapStateToProps 提供的值进行浅层比较,并决定是否重新渲染。

现在当你提供类似的数据时

{
    data: {
        ...reducerContent
    }
}

浅比较失败,因为您克隆了 reducerContainer,因此 nextProps.data 不等于 this.props.data。为了避免这种情况,您通常会选择memoization。为此,您可以使用reselect 或自己实现一个记忆函数

选择你的 mapStateToProps 看起来像

const getReducedDataSelector = createSelector(
   state => state.reducerContent,
   (reducedContent) => ({...reducedContent})
);
function mapStateToProps(state,ownProps) {
    return {
        data: getReducedDataSelector(state, ownProps);
    }
}

在上述情况下,getReducedDataSelector 也可以使用自定义记忆方法实现

【讨论】:

    猜你喜欢
    • 2020-06-01
    • 1970-01-01
    • 2019-06-18
    • 2020-11-27
    • 2018-03-24
    • 1970-01-01
    • 2021-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多