0
votes

I am trying to get my head around React & Redux,

I am fetching some data from an api that I have written, and trying to render that data into one of my components. The data returned is a simple JSON object that looks like this,

{
"brief": "No brief given",
"tasks": [
    {
        "_id": "5c74ffc257a059094cf8f3c2",
        "task": "XXX Task 7",
        "project": "5c7458abd2fa91567f4e4f03",
        "date_created": "2019-02-26T08:58:42.260Z",
        "__v": 0
    }
],
"_id": "5c7458abd2fa91567f4e4f03",
"owner": {
    "_id": "5c5af553eea087426cd5f9b9",
    "name": "Test test",
    "email": "[email protected]",
    "avatar": "placeholder.jpg",
    "password": "$2a$10$dsGdQZ4APnmAVjbII4vX4u7bCEm0vjxGtHAJ8LijrcBBNTHSn9d5i",
    "created_at": "2019-02-06T14:55:15.321Z",
    "__v": 0
},
"name": "XXX Project 1",
"status": "Pending",
"slug": "XXX-project-1",
"created_at": "2019-02-25T21:05:47.643Z",
"__v": 0

}

I retrieve this data via an action in my componentDidMount() function in my component like this,

       import React, { Component } from "react";
import PropTypes from "prop-types";
import { withRouter } from "react-router-dom";
import { connect } from "react-redux";
import { getProject } from "../../actions/projectActions";
import Dropdown from "react-dropdown";
import Avatar from "../profile/Avatar";
import ProjectPlaceholder from "../../img/new-project.svg";

import "react-dropdown/style.css";
import "../../css/project.scss";

class Project extends Component {
  constructor() {
    super();
  }

  componentDidMount() {
    const { id } = this.props.match.params;
    this.props.dispatch(getProject(id));
  }

  render() {
    console.log(this.props.project.name)
  }

Project.propTypes = {};

const mapStateToProps = state => ({
  project: state.project.project,
  errors: state.errors
});

export default connect(mapStateToProps)(Project);

This is my action,

    import axios from "axios";

import { GET_PROJECT, GET_ERRORS } from "./types";

// Set logged in user
export const getProject = slug => dispatch => {
  axios
    .get(`/api/projects/${slug}`)
    .then(res => {
      console.log(res);
      dispatch({
        type: GET_PROJECT,
        payload: res.data
      });
    })
    .catch(err =>
      dispatch({
        type: GET_ERRORS,
        payload: err.response.data
      })
    );
};

and here is my reducer,

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

const initialState = {};

export default function(state = initialState, action) {   
    switch (action.type) {
        case GET_PROJECT:
            return {
                ...state,
                project: action.payload
            };
        default:
            return state;   
    } 
}

So 1) I cannot work why in my mapToProps function I need to using state.project.project when all that gets returned is JSON object, and 2) why in my render method the console.log logs undefined?

Can anyone help me please?

2

2 Answers

1
votes

1. I cannot work why in my mapStateToProps function I need to using state.project.project when all that gets returned is JSON object

You always need to access it has state.project.project because state is something which is injected by connect and project is your data slice name in the store, so you need to specify which is the data slice you would like to fetch the data from, because you have used combineReducers in store.

2. why in my render method the console.log logs undefined.

This is because of your initialState in your reducer is { } and you are filling this using an async call in componentDidMount, when render() gets it it's undefined.

0
votes

Assuming that res.data contains the json object that you specified in your question, and you named your reducer property as project, it should contain the project property , .i.e, the code should work fine. You can try logging the payload within the reducer / action to check if the api is sending the data properly. You can also set the initial value for project as {} ( empty object ) so that you don't get state.project.project as undefined at initial render. Kindly check if it is properly set up.

You can also check console for any errors and also use redux-logger middleware to log all the actions dispatched - which will give you an idea of what is happening inside redux.