React,Redux,mapStateToProps,尽管状态发生了变化,但没有重新渲染

时间:2018-06-10 15:59:02

标签: javascript reactjs redux react-redux

我对Redux和React有一个奇怪的问题。 状态发生了正确的变化,在mapStateToProps中,我也得到了正确的新状态,但在映射之后,组件将不会重新渲染。

这样,组件不会重新渲染:

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

class ListItem extends Component {
    render() {
       return (<li>{this.props.item.text}</li>);
    }
}

const mapStateToProps = (state, ownProps) => {
    return {
        item: state.test.byID[ownProps.itemID]
    };
}

export default connect(mapStateToProps)(ListItem);

但是,如果我拆分项目,那么组件会重新渲染:

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

class ListItem extends Component {
    render() {
       return(<li>{this.props.text}</li>);
    }
}

const mapStateToProps = (state, ownProps) => {
    return {
        id: state.test.byID[ownProps.itemID].id,
        text: state.test.byID[ownProps.itemID].text
    };
}

export default connect(mapStateToProps)(ListItem);

我不知道为什么。

减速机:

const startState = {
    byID: {
        'a1': {id: 'a1', text: 'test1'},
        'a2': {id: 'a2', text: 'test2'},
        'a3': {id: 'a3', text: 'test3'},
        'a4': {id: 'a4', text: 'test4'},
        'a5': {id: 'a5', text: 'test5'},
        'a6': {id: 'a6', text: 'test6'},
        'a7': {id: 'a7', text: 'test7'},
    },
    all: ['a1', 'a2','a3', 'a4', 'a5', 'a6', 'a7']
};


export default function reducer(state = startState, action) {
    switch (action.type) {
        case 'ADD_TEXT':
            const newState = {...state};
            newState.byID[action.id].text = action.text;
            return newState
        default:
            return state;
    }
}

有什么想法吗?

1 个答案:

答案 0 :(得分:3)

假设您要更改text个数组对象中的byID字段。使用您的代码:

newState.byID[action.id].text = action.text;

您正在改变您的状态,因此React可能在识别更改时遇到问题,因为item道具中对象的引用不会改变,只会改变它的属性。如果有检查,它就不会重新渲染,因为它“假设”对象根本不会改变。

在第二种情况下,您将返回prop text这是字符串类型,因此不会像对象那样进行浅层检查,并且相等的比较===将区分更改并正确地重新呈现组件

有关更多说明,您可能需要查看Immutability in React

通过传播运营商保持不变性的想法:

const newState = {...state};

可以进行顶级引用,但不适用于嵌套子对象:

  

对象传播执行对象的浅表副本。仅克隆对象本身,而不克隆嵌套实例。 An easy guide to object rest/spread properties in JavaScript

虽然变异对象似乎是您提供的代码中最容易出错的部分,但Component React类可以深入调查对象更改(PureComponent没有)和问题可能与另一个问题有关。