Reactjs 如何允许connect基于状态更改重新渲染对象

Reactjs 如何允许connect基于状态更改重新渲染对象,reactjs,redux,Reactjs,Redux,在下面的示例中,我希望组件在更新列表时重新加载。但是,即使connect被传递到新状态,它也不会重新启动组件 我知道connect执行浅层比较,但不知道如何使其比较对象的值。我找不到任何启用选项的连接示例 我看过很多,但也没用 我试过了 const ConnectList = connect(mapStateToProps,null,null,{areStatesEqual : () => false})(List) 只要试着让它在任何改变后重新上市。这似乎不太管用 import Rea

在下面的示例中,我希望组件在更新列表时重新加载。但是,即使connect被传递到新状态,它也不会重新启动组件

我知道connect执行浅层比较,但不知道如何使其比较对象的值。我找不到任何启用选项的连接示例

我看过很多,但也没用

我试过了

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')
);
import React,{Component}来自'React';
从“react dom”导入react dom
从“redux”导入{createStore}
从“redux thunk”导入thunk
从“react redux”导入{connect,Provider}
函数testReducer(状态=null,操作){
log(`Reducer:Reducer接收到操作${action.type}.${action.comment}`)
开关(动作类型){
个案"名单":{
返回({…状态,列表:action.list})
}
“其他”案例:{
返回({…状态,其他:action.other})
}
违约:
返回状态
}
}
函数testAction(){
返回{
键入:“列表”,
列表:[“第一”、“第二”],
注释:`这将触发connect()和mount组件列表mount,因为reducer和connect在该操作后都会更改状态`
}
}
函数testActionChange(){
返回{
键入:“列表”,
列表:[“第一”、“第二”、“第三”],
注释:`这将触发connect()和mount组件列表mount,因为reducer和connect在该操作后都会更改状态`
}
}
函数testOther(){
返回{
键入:“其他”,
other:`some other value`,
注释:`这将触发connect(),但不会装载组件列表,因为connect()的返回不会更改`
}
}
函数inertAction(){
返回{
类型:'惰性',
注释:“此操作不应触发connect()或mount Component List,因为reducer返回相同的状态”
}
}
const store=createStore(testReducer,[thunk])
store.dispatch(testAction())
//2秒后发送一个操作
setTimeout(store.dispatch.bind(null,testOther()),2000)
setTimeout(store.dispatch.bind(null,inertAction()),4000)
setTimeout(store.dispatch.bind(null,testActionChange()),6000)
类列表扩展组件{
componentDidMount(){
log(`Component List mounted`)
}
render(){
const{list}=this.props
返回(
{list.map((元素)=>{
返回()
})}
)
}
}
函数mapstatetops({list}){
log(`connect()已触发`)
报税表({
列表
})
}
const ConnectList=connect(mapStateToProps)(列表)
类元素扩展组件{
render(){
const{element}=this.props
返回(
{element}
)
}
}
ReactDOM.render(
, 
document.getElementById('root'))
);
输出

在connect中添加了console.log。

我不知道您在MapStateTops中使用的语法

尝试:


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

connect触发器。但问题是它不会呈现组件。你可以控制台。记录每次状态更改时MapStateTops返回的内容吗?我补充道。但也注意到了其他一些事情。即使componentDidMount没有被调用,render确实被调用可能会使用shouldComponentUpdate(nextrops)并在那里进行比较,而不是将其向下推到renderI。我想,没有办法调用componentDidMount,只会调用render
function mapStateToProps(state){
    console.log(`connect() triggered`)
    const list = state.list;
    return { list };
}