2

enter image description here

My intention is to do something very basic. I just want my name to appear in the HelloPage container upon rendering and, then, with a click turn my name into "Bob." I presume I'm missing something stupid.

HelloPage.js (container, where my name should appear, but is totally undefined)

import React from 'react';
import PropTypes from 'prop-types';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import * as actions from '../actions/helloActions';

export const HelloPage = ({name, actions}) => {
  return (
    <div>
      My name is {name}. This is the hello page.
      <div onClick={() => actions.sayHello()}>But my name could be different.</div>
    </div>
  );
};

HelloPage.propTypes = {
  actions: PropTypes.object.isRequired,
  name: PropTypes.string.isRequired
};

function mapStateToProps(state) {
  return {
    name: state.name
  };
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(actions, dispatch)
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(HelloPage);

I'm guessing that the culprit is in the reducer where I set the initial state. Does the initial state just not get set early enough? Does this part of the code look right?

import { SAY_HELLO } from '../constants/actionTypes';
import objectAssign from 'object-assign';
import initialState from './initialState';

export default function helloReducer(state = initialState.hello, action) {

  switch (action.type) {
    case SAY_HELLO:
      return objectAssign({}, state, { name: "Bob" });
    default:
      return state;
  }
}

This is the way I have the initialState file set up:

export default {
  hello: {
    name: 'Gabriel'
  }
};

And, the way I'm combining the reducers:

import { combineReducers } from 'redux';
import fuelSavings from './fuelSavingsReducer';
import hello from './helloReducer';
import {routerReducer} from 'react-router-redux';

const rootReducer = combineReducers({
  fuelSavings,
  hello,
  routing: routerReducer
});

export default rootReducer;

The other containers/components of the app are working perfectly, but just this new container isn't. I'm using the react slingshot boilerplate. Just added one extra route. I copied the structure that was there in the boilerplate.

Gabriel Kunkel
  • 2,643
  • 5
  • 25
  • 47
  • 1
    Try changing `function mapStateToProps(state) { return { name: state.name }; }` to `function mapStateToProps(state) { return { name: state.hello.name }; }` – Hardik Jain Apr 14 '17 at 15:46
  • @HardikJain Okay, now it works. Thanks. (Feel free to copy and paste it into an answer.) – Gabriel Kunkel Apr 14 '17 at 15:54

1 Answers1

4

The initial state for 'name' is defined at the second level of the object 'hello'.

So to access it,you need to change your mapStateToProps function as:

function mapStateToProps(state) { 
  return { 
   name: state.hello.name 
  };
}
Hardik Jain
  • 184
  • 8