Codepen simple React-Redux Project Not working

I’m creating a really simple project in Codepen using React-Redux. Currently, it’s not working as my react components seem like they can’t even access the properties passed in using the Redux connect function. I can’t seem to find what I’m doing wrong.

//When completed, this project should have a text field and a button. When the button is pressed, a number is added to the text field, with each subsequent number being 1 greater than the last. Currently: Some sort of error where I can't access this.props.nums (my list of numbers) inside my react components. Does this mean my React and Redux code isn't connected properly?


//Import modules, initialize Provider and connect objects
const { Provider, connect } = ReactRedux;
const { applyMiddleware, createStore, combineReducers, bindActionCreators } = Redux;

//constants that corresponding to action types
const ADD_NUM = "addNum";

//action creator that returns type addnum and the number
let addNum = (num) => {
  return {
    type: ADD_NUM
  };
}

//the reducer that handles the add
let addReducer = (state = {num: 0, nums: [0]}, action) => {
  switch(action.type){
    case ADD_NUM:
      return {num: state.num + 1, nums: state.nums.concat(state.num)};
      //CHANGE THIS
    default:
      return state;
  }
  
}

//combined reducer here
const rootReducer = combineReducers({
  add: addReducer
});

//create store
let store = createStore(rootReducer);

//define first component, a button
class ReduxButton extends React.Component {
  
  onClick(e) {
    e.preventDefault();
    
    this.props.addNum(this.props.num);
    
    //it seems that no props are being passed into the react component from the console logging
    console.log(this.props.nums, this.props.num);
    console.log(store.getState());
  }
  
  render(){
    console.log(this.props.nums);
    return (
      
      <div>
        <button onClick={this.onClick.bind(this)}>
          Add next number
        </button>
      </div>
    
    );
  }
  
  
  
}

//second function displays the numbers
class ReduxTextField extends React.Component {
  
  renderList(){
    return this.props.nums.map((num) => <li key={num}>{num}</li>);
                               
  //it seems that the above code doesn't work, and this.props.nums isn't even defined???
    
  }
  render(){
    
    return (
    <ol type="I">{this.renderList()}</ol>
    );
  }
  
}

//map state message to property of the component

let mapStateToProps = function(state) {
    return {num: state.num, nums: state.nums};
}

//map dispatch functions in redux to react component props

let mapDispatchToProps = (dispatch) => {
  return {
    addNum: (num) => {
      dispatch(addNum(num));
    }
  };
}
//use connect to use the map functions and connection react to redux

const ReduxButtonContainer = connect(mapStateToProps, mapDispatchToProps)(ReduxButton);

const ReduxTextFieldContainer = connect(mapStateToProps, mapDispatchToProps)(ReduxTextField);

//Create the ultimate app component, containing the button and text

class App extends React.Component {
  
  render() {
    return (
      <div>
        <ReduxTextFieldContainer />
        <ReduxButtonContainer />
      </div>
    );
     
  }
}

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

console.log(store.getState());

Are you still struggling with this? Can you provide a link to this codepen?

Yes. You can view my code here: https://codepen.io/albertzed2000/pen/ZEbXPgR

Also, for some reason codepen is not reading part of my code anymore (the bottom of my code, from lines 86 to 125 seem to be whited out and I can’t understand why). Thank you!

Hi,

there’s a variety of issues here, that combine to cause you trouble:

  • the div tag in in line 77 needs to be a closing tag
  • addReducer needs another closing curly bracket
  • you need to load react and react-dom before you load react-redux (in the settings)
  • make sure you use compatible versions of your dependencies (react and react-dom versions should be the same for example). I’d suggest you remove them all and pull in the latest versions using the Search in codepen

You’ll still have errors after that, but maybe you can solve those. If not, let me know.

1 Like

Thank you kind stranger! After your fixes, the only thing I had to change to get the code to work properly was pass the addReducer into the createStore function rather than a combined reducer. Your comments helped alot and I would have given up on this without you, so I’m very grateful. However, I’m not really understanding how one would go about with using Redux.combineReducers(). I read the combineReducers usage official documentation and it says the new (root)Reducer created by combine reducer essentially ‘calls’ all the reducers? If that’s the case, why won’t the code function the same when I pass rootReducer rather than addReducer on lines 26-32? Am I misunderstanding how combineReducers is used?

Thanks

That’s good to hear - I’m glad it was helpful.

The way you’ve used combineReducer, the state becomes an object with a property adder. So if you do that, you need to change mapStateToProps to

let mapStateToProps = function(state) {
    return {nums: state.adder};
}

Alternatively, you could change your root reducer to

const rootReducer = Redux.combineReducers(addReducer);

Ah, thank you for clearing up my misunderstanding, that was much appreciated!