简体   繁体   中英

getDerivedStateFromProps Does not re-render after Redux Reducer state is updated

I'm using the new getDerivedStateFromProps since componentWillReceiveProps was deprecated. However it does not seem to work as expected, as nothing happens after I update the Redux state.

Expected

  • Action / Reducer is updated
  • Component Main's props.modal is updated and the component re-renders

Results

  • Action / Reducer is updated
  • Nothing happens in the Main Component

"react": "^16.3.2",
"react-dom": "^16.3.2",

Note here in this screenshot, I'm able to update the Redux state, modal has been updated, yet my component does not update and re-render.

在此输入图像描述

I expect this code to be called a 2nd time:

static getDerivedStateFromProps(nextProps, nextState) {
  const { modal } = nextProps;
  console.log('getDerivedStateFromProps', nextProps);
  console.log(' nextState', nextState);
  return { modal };
}

Or at least the console.log's in my render method to be called a twice time, this never happens. Any ideas why?

Component code:

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

 // MUI
 import { withStyles } from "@material-ui/core/styles";

 // Components
 import TopNav from "components/Common/topNav";
 // import ProductModal from 'components/Common/productModal';

 // Utils
 import { findNotification, showNotification } from "utils/notifications";

 const styles = {
  root: {
    flexGrow: 1,
    display: "flex",
    flexDirection: "column",
    height: "100%"
  }
  };

  class Main extends Component {
   static getDerivedStateFromProps(nextProps, nextState) {
    const { modal } = nextProps;
    console.log("getDerivedStateFromProps", nextProps);
    console.log(" nextState", nextState);
    return { modal };
}

constructor(props) {
    super(props);

    this.state = {
        modal: {}
    };
}

componentDidUpdate(props) {
    console.log("componentDidUpdate", props);
}

render() {
    const {
        classes,
        children,
        notifications,
        currentNotification
    } = this.props;

    console.log("this.props", this.props);
    console.log("this.state", this.state);

    const notificationObj = findNotification(
        currentNotification,
        notifications
    );

    return (
        <div className={classes.root}>
            {/* <ProductModal /> */}
            <TopNav />
            {showNotification(notificationObj)}
            {children}
        </div>
    );
}
}

const mapStateToProps = ({ modal }) => ({
modal
});

export const MainJest = Main;

export default connect(
mapStateToProps,
null
)(withStyles(styles)(Main));

Reducer:

import {
  MODAL_CLOSE_MODAL,
  MODAL_SET_MODAL
} from 'actions/types';

export const initialState = {
  modal: {
    name: '',
    props: {}
  }
};

const modalsReducer = (state = initialState, { type, payload }) => {
  switch (type) {
    case MODAL_SET_MODAL:
      return {
        ...state,
        modal: {
          name: payload.modalName,
          props: payload.modalProps
        }
      };
    case MODAL_CLOSE_MODAL:
      return {
        ...state,
        modal: {
          name: '',
          props: {}
        }
      };
    default:
      return state;
  }
};

export default modalsReducer;

Turns out my problem was in the mapStateToProps

Needed to pull the state from modalsReducer

const mapStateToProps = (state) => {
  console.log('mapStateToProps state:', state);
  return state.modalsReducer;
};

Also needed to flatten my state inside the modalsReducer

import {
  MODAL_CLOSE_MODAL,
  MODAL_SET_MODAL
} from 'actions/types';

export const initialState = {
  modalName: '',
  modalProps: {}
};

const modalsReducer = (state = initialState, { type, payload }) => {
  switch (type) {
    case MODAL_SET_MODAL:
      return {
        ...state,
        modalName: payload.modalName,
        modalProps: payload.modalProps
      };
    case MODAL_CLOSE_MODAL:
      return {
        ...state,
        modalName: '',
        modalProps: {}
      };
    default:
      return state;
  }
};

export default modalsReducer;

So the Redux was not connected properly...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM