Redux state variables return undefined

Tried to follow a simple guide posted on this forum, but it’s returned undefined for the state variables ‘greeting’ and ‘name’. This is index.js in a create react app. What did I miss that is causing the state not to pass properly?

import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

import * as Redux from "redux";
import * as ReactRedux from "react-redux";
import ReduxDevtools from "redux-devtools";

const initial_state = {
  greeting : "hello",
  name : "joe"
};

const reducer = (prior_state = initial_state, action) => {
  switch (action.type) {
    case 'CHANGE_NAME':
      return {
        ...prior_state,
        name : action.payload.name
      };
    default:
      return prior_state;
  }
};


const store = Redux.createStore(reducer, initial_state, window.devToolsExtension && window.devToolsExtension());


// action creator / function hybrid
class TestComponent extends Component {
  
  handle_click = () => {
    const change_name_joseph = {
      type : "CHANGE_NAME",
      payload : { name : "Joseph" }
    };
    this.props.dispatch(change_name_joseph)
  };
  
  render() {
    return (
      <div>
        <h1>{`${this.props.greeting} to my friend ${this.props.name}`}</h1>
        <button onClick={() => this.handle_click}> Click here</button>
      </div>
    )
  }
}


ReactRedux.connect((initial_state) => {
  return {
    greeting : initial_state.greeting,
    name : initial_state.name
  }
})(TestComponent); // The arg for the returned function
// This is what RR will bind to.
// It also injects the dispatch function



// last step (or first?)
ReactDOM.render(
  <ReactRedux.Provider store={store}>
    <TestComponent />
  </ReactRedux.Provider>, document.getElementById('root'));


serviceWorker.unregister();

I think you are misusing connect. From the Redux docs:

It [connect] does not modify the component class passed to it; instead, it returns a new, connected component class for you to use.

So, you’ve got to save that returned component and that is what you give to your Provider (or whatever). For example, making these changes:

const TestComponentWrapped = ReactRedux.connect((initial_state) => {
  return {
    greeting : initial_state.greeting,
    name : initial_state.name
  }
})(TestComponent);

ReactDOM.render(
  <ReactRedux.Provider store={store}>
    <TestComponentWrapped />
  </ReactRedux.Provider>
  , document.getElementById('root'));

There are various ways to name it. But the important distiction here is that TestComponent is your component before it is wrapped in Redux and TestComponentWrapped is a new component that is wrapped in Redux. They are two different components. The TestComponentWrapped is what you use. TestComponent is only needed to pass into connect. (Although, in some situations it can also be used for unit testing.)

This usually isn’t an issue because often that component would be in it’s own file and the last thing you would do would be exporting that connected component, without actually naming it.

1 Like