10110
10110

Reputation: 2675

Redux store property gets nested into itself on update

I'm having this issue where my props are ending up looking like this (on console.log):

{
    fetchRoles: f(),
    roles:
        roles: ["Admin", "Manager"],
}

As you can see, somewhere in my code I'm making a mistake that causes the roles prop to get nested into itself, which would force me into doing const { roles } = this.props.roles; in order to retrieve my data (which works BTW).

I've looked around for help but not many people seem to have run into this issue (I'm just getting started with redux).

Below you can see my files:

rolesReducer.js:

import { FETCH_ROLES } from "../actions/types";

const initialState = {
  roles: [],
};

export default function (state = initialState, action) {
  const { roles } = action;
  switch (action.type) {
    case FETCH_ROLES:
      return {
        ...state, //also tried ...state.roles and same issue.
        roles,
      };
    default:
      return state;
  }
}

rolesActions.js:

import { FETCH_ROLES } from "./types";

const roles = ["SuperAdmin"];

export function fetchRoles() {
  return function (dispatch) {
    dispatch({
      type: FETCH_ROLES,
      roles,
    });
  };
}

reducers/index.js (root reducer):

import { combineReducers } from "redux";
import rolesReducer from "./rolesReducer";
import roleMembersReducer from "./roleMembersReducer";

export default combineReducers({
  roles: rolesReducer,
  roleMembers: roleMembersReducer,
});

PermissionsManager.jsx:

import React, { Component } from "react";
import { connect } from "react-redux";
import { Container } from "react-bootstrap";
import { fetchRoles } from "../redux/actions/rolesActions";

import RoleContainer from "./RoleContainer";

class PermissionsManager extends Component {
  componentDidMount() {
    this.props.fetchRoles();
  }

  render() {
    console.log(this.props);
    const { roles } = this.props.roles;
    return (
      <Container>
        {roles.map((role) => {
          return <RoleContainer key={role} role={role} />;
        })}
      </Container>
    );
  }
}

const mapStateToProps = (state) => {
  return {
    roles: state.roles,
  };
};

export default connect(mapStateToProps, { fetchRoles })(PermissionsManager);

Edit 1 - Adding reducer log:

As suggested, I logged the reducer, specifically state and action:

state:

{
    roles: [],
}

action:

{
    roles: ["Admin", "Manager"],
    type: "FETCH_ROLES",
}

No duplication or abnormal structures I believe.

Upvotes: 0

Views: 117

Answers (1)

maioman
maioman

Reputation: 18754

One way to shape the store like you're asking is to flatten roles in rolesReducer.js,
you can do so storing the received array directly in the partial state:

initialState would need to look like

const initialState = []

and in the switch statement

 case FETCH_ROLES:
  return roles

Upvotes: 1

Related Questions