0

I just wanted to integrate a new Container in my React App, wired it up with Redux and just wanted to see it's all working. It's not however. accessing the reducer via this.props.selection gives me undefined. I don't know why. It does work in other containers, and the reducer has some well-defined initial state. - I'm not sure I see what the difference is here? Am I missing something trivial?

import React, { Component } from 'react'
import { connect } from 'react-redux';
import {bindActionCreators} from 'redux';

export class AudioPlayer extends Component {
  constructor(props) {
    super(props);
    this.state = { someComponentState : true }
  }

  onLog() {
    console.log("Logging:");
    console.log(this.props.selection); // gives me: undefined
  }
  render() {    
    return (
      <div>
           <button onClick={()=> this.onLog()}>LOG</button>
      </div>
    )
  }
}

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

export default connect(mapStateToProps)(AudioPlayer);

PS: I've simplified this component somewhat, but I think it should still reflect the problem.

edit: reducer example people have asked to see the reducer, however, I've tried this with several reducers that are already implemented in the app and are working in other containers, so I don't think this is where the problem lies - but who knows:

import { SELECT_ITEM } from '../actions/types';

export default function(state = {}, action) {
  switch(action.type) {
    case SELECT_ITEM: 
      return {...state, error:'', selected: true};
  }

  return state;
}

edit2: mapStateToProps does not seem to be called at all I just tried to do a console.log in mapStateToProps, to see if it's called, and seems that it never is. Nothing is ever logged. What could be the reason for this?

function mapStateToProps (state) {
    console.log("In map function");
    console.log(state);

  return {
    selection: state.selection, //both return
    auth: state.auth            // undefined
  };
}

I also added another reducer (auth) which works elsewhere in the app, but here returns undefined.

edit3: My Root Reducer

import { combineReducers } from 'redux';
import { reducer as form } from 'redux-form';

//reducer imports
import authReducer from './auth_reducer';
import articlesReducer from './articles_reducer';
import userReducer from './user_reducer';
import currentSelectionReducer from './currentSelection_reducer';

const rootReducer = combineReducers({
  auth: authReducer,
  user: userReducer,
  articles: articlesReducer,
  selection: currentSelectionReducer,
});

export default rootReducer;
R. Kohlisch
  • 2,823
  • 6
  • 29
  • 59
  • Can you show the code where the `initialState` is being set? – Anand Undavia Nov 26 '18 at 12:28
  • I have tried this with several reducers already implemented in the app and which are already being used. So it would be strange if the problem is in the reducer code itself. I can add it though, sure. – R. Kohlisch Nov 26 '18 at 12:29
  • Yeah, from the code, I feel that `state.selection` is undefined and because of which you are getting `this.props.selection` as undefined – Anand Undavia Nov 26 '18 at 12:30
  • Yeah that's what it looks like, but I'm successfully accessing it in other places in the app and initialise it as an empty object. Oh, and what's also interesting is that **no matter which reducer I use** (my app has multiple), it always gives me undefined in that component, whereas in others its fine. – R. Kohlisch Nov 26 '18 at 12:33
  • Umm the reducer you have provided works on `selected ` field. In which reducer are you managing the `selection` field? – Anand Undavia Nov 26 '18 at 12:39
  • Are you using the "Redux DevTools" extension? Here is a [link](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd?hl=en) for Chrome, but you do need to connect it though, a simple example [here](https://github.com/Xorifelse/pizza-configurator/blob/master/src/store.js) – Xorifelse Nov 26 '18 at 12:42

3 Answers3

1

your component code is fine.

In your reducer it should be

export default function(state = { selected: false }, action) {

Further reading:

Felix K.
  • 14,171
  • 9
  • 58
  • 72
  • thank you. this is not solving the error I am getting though. I just tried, I still get `undefined` – R. Kohlisch Nov 26 '18 at 12:36
  • it should. please double check. – Felix K. Nov 26 '18 at 12:39
  • Also check whether you are accessing the correct reducer. Put a console.log inside your `function mapStateToProps (state) {` to see your whole state. – Felix K. Nov 26 '18 at 12:40
  • I double checked, it's not working. Did the console log thing just now, it doesnt seem to go into the mapStateToProps at all. See my edit no. 2. Thanks a lot for your help btw. – R. Kohlisch Nov 26 '18 at 12:43
  • you are welcome :) glad you found your problem via the accepted solution. it was indeed tricky ;) – Felix K. Nov 26 '18 at 13:13
1

Can you try removing 'export' from 'export class AudioPlayer extends Component'

you can also check this: mapStateToProps not getting called at all

Rakesh Makluri
  • 647
  • 4
  • 10
1

1) In your debugging please check it enters the exact case in the reducer, that it understands the action.type == SELECT_ITEM, and returns the new state.

2) Also notice selection is an object, which contain the 'selected' inside it. Your 'selection' reducer contains: {...state, error:'', selected: true}

maybe there is a confusion about this?