Jonas
Jonas

Reputation: 7945

componentDidUpdate not firing after redux state change

I have these Reducers:

const initialState = {
    categories: [],
    programms: {}
}

export const programmReducers = (state = initialState, action) => {
    let programms = state.programms;

    switch (action.type) {
        case actionTypes.FETCH_CATEGORIES:
            return Object.assign({}, state, {
                categories: action.payload
            })
        case actionTypes.FETCH_PROGRAMM:
            programms[action.payload.id] = action.payload;
            console.log(programms);
            return {
                ...state,
                programms: Object.assign({}, programms)
            }
        case actionTypes.FETCH_PROGRAMM_COMPONENTS:
            programms[action.programmId].components = action.payload;
            console.log('Added Components')
            return {
                ...state,
                programms: programms
            }
        default:
            return state
    }
}

The last one (FETCH_PROGRAMM_COMPONENTS) adds an array to an object in the programm object. This works but somehow it won't fire componentDidUpdate in my component. It works for FETCH_PROGRAMM though.

class ProgrammPage extends Component {

    static async getInitialProps({ store, query: {id} }) {
        let programm;
        if (!store.getState().programm.programms[id]) {
            console.log('Programm not! found');
            programm = await store.dispatch(loadProgramm(id));
            await store.dispatch(loadProgrammComponents(id));
        } else {
            programm = store.getState().programm.programms[id];
            console.log('Programm found')
        }

        return {
            // programm: programm
            programmId: id
        }
    }

    componentDidUpdate(prevProps) {
        console.log('UPDATE', this.props, this.props.programm.components.length)
        if (!prevProps.user && this.props.user) {
            this.props.loadProgrammComponents(this.props.programmId);
        }
    }

    render() {
        return (
            <div>
                <h1>Programm</h1>
                <h2>{this.props.programm.name}</h2>
                <h2>{this.props.programm.id}</h2>
                <h3>Components: {this.props.programm.components ? this.props.programm.components.length : 'None'}</h3>
                <br></br>
                <h1>User: { this.props.user ? this.props.user.uid : 'None'}</h1>
                <button onClick={() => this.props.loadProgramm('ProgrammLevel2')}>Load Programm</button>
                <button onClick={() => this.props.loadProgrammComponents(this.props.programmId)}>Load Components</button>

            </div>
        )
    }
}

function mapStateToProps(state) {
    return {
        programm: state.programm.programms['ProgrammLevel1'],
        programms: state.programm.programms,
        user: state.auth.user
    }
}

const mapDispatchToProps = dispatch => bindActionCreators({
    loadProgrammComponents,
    loadProgramm
}, dispatch)

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(ProgrammPage)

Upvotes: 0

Views: 1115

Answers (1)

Dennis Vash
Dennis Vash

Reputation: 53994

You returning the same reference.

Try returning a copy of programms array: [...programms] ( or Object.assign() if it's an Object).

    case actionTypes.FETCH_PROGRAMM_COMPONENTS:
        programms[action.programmId].components = action.payload;
        console.log('Added Components')
        return {
            ...state,
            programms: [...programms]  // <-- Return new state
        }

Upvotes: 2

Related Questions