如何允许连接根据状态更改重新呈现对象

时间:2018-07-08 12:46:57

标签: reactjs redux

在下面的示例中,我希望组件在列表更新时重新呈现。但是,即使connect传递了新状态,它也不会重新呈现该组件。

我知道connect执行浅比较,但是不知道如何使它比较对象的值。我找不到在启用选项的情况下进行连接的任何示例。

我见过How does a redux connected component know when to re-render?等,但这也无济于事。

我尝试过

const ConnectList = connect(mapStateToProps,null,null,{areStatesEqual : () => false})(List)

只是尝试使其重新呈现任何更改。看来效果不佳。

import React, { Component } from 'react';
import ReactDOM from 'react-dom'
import {createStore} from 'redux'
import thunk from 'redux-thunk'
import {connect, Provider} from 'react-redux'

function testReducer (state=null,action) {
    console.log(`Reducer: Reducer received action ${action.type}. ${action.comment}`)
    switch(action.type){
        case 'LIST': {
            return ({ ...state, list: action.list })
        }

        case 'OTHER': {
            return ({ ...state, other: action.other })
        }
        default:
            return state
    }

}

function testAction() {
    return {
        type: 'LIST',
        list: ['first','second'],
        comment: `This will trigger both connect() and mount Component List mount because, both reducer and connect changes state after this action`
    }
}

function testActionChange() {
    return {
        type: 'LIST',
        list: ['first','second','third'],
        comment: `This will trigger both connect() and mount Component List mount because, both reducer and connect changes state after this action`
    }
}

function testOther() {
    return {
        type: 'OTHER',
        other: `some other value`,
        comment: `This will trigger connect(), but not mount Component List because the return from connect() doesn't change`
    }
}

function inertAction() {
    return {
        type: 'INERT',
        comment: 'This action should not trigger either connect() or mount Component List , because reducer returs the same state'
    }
}

const store = createStore(testReducer, [thunk])

store.dispatch(testAction())

//Dispatch an action after 2 secs
setTimeout(store.dispatch.bind(null,testOther()),2000)
setTimeout(store.dispatch.bind(null,inertAction()),4000)
setTimeout(store.dispatch.bind(null,testActionChange()),6000)


class List extends Component {

    componentDidMount(){
        console.log(`Component List mounted`)
    }

    render(){
        const {list} = this.props
        return(
            <div>
                {list.map((element) => {
                    return(<Element key={element} element={element} />)
                })}
            </div>
        )
    }
}

function mapStateToProps({list}){
    console.log(`connect() triggered`)
    return( {
        list
    })
}

const ConnectList = connect(mapStateToProps)(List)

class Element extends Component {
    render(){
        const {element} = this.props
        return(
            <div>{element}</div>
        )
    }
}

ReactDOM.render(<Provider store={store}> 
                    <ConnectList />
                </Provider>, 
                document.getElementById('root')
);

输出

enter image description here

在connect中添加了console.log。 enter image description here

2 个答案:

答案 0 :(得分:1)

我无法识别您在mapStateToProps中使用的语法

尝试:

function mapStateToProps(state){
    console.log(`connect() triggered`)
    const list = state.list;
    return { list };
}

答案 1 :(得分:0)

我发现connect实际上调用了该组件。但是只有render方法。因此,我必须将在componentDidMount上的动作创建者调用移动到redux中的中间件,以便在状态更改时添加适当的调度程序。