Piccaza De
Piccaza De

Reputation: 519

Why React Redux context.store is undefined in child component?

I am trying to access store from child components, but its always undefined, and due to this I have to pass the properties to child component.

This is the main app starting point:

ReactDOM.render(
  <Provider store={store}>
    <SignUpContainer />
  </Provider>,
  container
);

Where SignUpContainer is:

const SignUpContainer = connect(
  mapStateToProps,
  mapDispatchToProps
)(SignUpComponent);

Where SignUpComponent is a normal react component:

export default class SignUpComponent extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div className={"sign-up-component " + this.context.store.theme}>
        // Form
      </div>
    )
  }
}

I am always getting context.store as undefined. Is there anything wrong to define the context.

I am looking to access the store details implicitly in child component (and children in the sub levels) without explicitly passing them.

React version is: 16.8.6.

Upvotes: 4

Views: 1466

Answers (2)

Nicholas
Nicholas

Reputation: 3784

Usually you will pass the desired props to the component when you connect to the store through mapStateToProps and then you access as regular props in your component.

so for example

// State of type StoreType
const mapStateToProps = (state: StoreType) => ({
  theme: state.theme
});

class Button extends React.Component {
  render() {
    return (
      <button className={"button " + this.props.theme}>
        Button
      </button>
    )
  }
}

export default connect(
      mapStateToProps
    )(Button);

Upvotes: 1

Yevhen Horbunkov
Yevhen Horbunkov

Reputation: 15550

I'm guessing there's something wrong in the way you try to pass required part of the state to your component, since you should refer to component prop, which state variable theme is mapped onto with mapStateToProps(), rather than this.context.store.theme.

You may find below the distilled example of how that should be done, hope that gives you the clue:

//dependencies
const { render } = ReactDOM,
      { createStore } = Redux,
      { connect, Provider } = ReactRedux
      
//store initialization
const defaultState = {
        someProp: 'propValue',
        anotherProp: 'justAnotherValue',
        theme: 'someTheme'
      },
      appReducer = (state=defaultState, action) => state,
      store = createStore(appReducer)
//custom component
const MyComponent = ({componentTheme}) => (
  <div>
    the theme is {componentTheme}
  </div>
)
//custom component wrapper
const mapStateToProps = ({theme}) => ({componentTheme: theme}),
      MyContainer = connect(mapStateToProps)(MyComponent)
//provider wrapper
render(
  <Provider store={store}>
    <MyContainer />
  </Provider>,
  document.getElementById('root')
)
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script><script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script><script crossorigin src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.4/redux.min.js"></script><script crossorigin src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.1.1/react-redux.min.js"></script><div id="root"></div>

Upvotes: 0

Related Questions