title: Redux and React. Uncaught TypeError: Cannot read property 'dispatch' of undefined
body: <p>I'm trying to call dispatch from deeply nested component.
  I'm using Redux and React. </p>
  
  <p>My app structure is:</p>
  
  <p>[App]</p>
  
  <p>----[Main]</p>
  
  <p>--------[ShopCoffee]</p>
  
  <p>--------[Other components]</p>
  
  <p>When I call 'dispatch' from app.jsx it works.</p>
  
  <p>When I call 'dispatch' from Main component it works, when I call dispatch from render() method (it has warnings, but still works), but doesn't work when I call 'dispatch' from other place.</p>
  
  <p>I pass store using Provider and addNewItemToCart() as props, but when I call addNewItemToCart from the ShopCoffee component, there is an error:
  "Uncaught TypeError: Cannot read property 'dispatch' of undefined"</p>
  
  <p>Here is my program:</p>
  
  <p>App.jsx</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>import React from "react";
  import ReactDOM from "react-dom";
  
  import Main from "./components/main.component.jsx";
  import { createStore } from "redux";
  import { Provider } from "react-redux";
  
  var app = document.getElementById("app");
  
  function mainAppReducer(state, action) {
   if (!state) return {
    text: 'test text 1231'
   }
   switch (action.type) {
    case 'ADD_TO_CART' : console.log('ADD_TO_CART');
    return Object.assign({}, state, { text : action.text });
   }
  }
  const store = createStore(mainAppReducer);
  
  store.dispatch ({
   type : 'ADD_TO_CART',
   text : 'One more message! ;)'
  });
  
  store.dispatch ({
   type : 'ADD_TO_CART',
   text : 'Text text message from redux! ;)'
  });
  
  console.log("store.getState() == ", store.getState());
  
  var render = () =&gt; ReactDOM.render(&lt;Provider store={store}&gt;&lt;Main /&gt;&lt;/Provider&gt;, app);
  store.subscribe(render);
  render();
  
  console.log("store.getState() == ", store.getState());</code></pre>
  </div>
  </div>
  </p>
  
  <p>main.component.jsx </p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>import React from "react";
  import Header from "./header.component.jsx";
  import Footer from "./footer.component.jsx";
  import Cart from "./cart.component.jsx";
  import Checkout from "./checkout.component.jsx";
  import ShopCoffee from "./shop-coffee.component.jsx";
  import Rent from "./rent.component.jsx";
  import Repair from "./repair.component.jsx";
  import Contacts from "./contacts.component.jsx";
  import { connect } from "react-redux";
  
  export class Main extends React.Component {
   constructor(props) {
    super(props);
   }
   addNewItemToCart(itemsInCart) {
    console.log("works");
    console.log("addNewItemToCart() :: itemData == ", itemsInCart);  
    console.log("from Main: this.props", this.props);
    this.props.dispatch({type : 'ADD_TO_CART'});
   
   }
  
   getItemsInCart(itemsInCart) {
    console.log("getItemsInCart() :: itemData == ", itemsInCart);
    return itemsInCart;
   }
  
   render() {
    console.log('(from render) this.props == ', this.props);
    console.log('dispatch==', this.props.dispatch);
    
    return (
     &lt;main&gt;
      &lt;Header /&gt;
      &lt;Cart getItemsInCart = {this.getItemsInCart} /&gt;
      &lt;Checkout /&gt;
      &lt;ShopCoffee addNewItemToCart = {this.addNewItemToCart}/&gt;
      &lt;Rent /&gt;
      &lt;Repair /&gt;
      &lt;Contacts /&gt;    
      &lt;Footer /&gt;
     &lt;/main&gt;
    );
   }
  }
  
  export default connect((store) =&gt; store)(Main);</code></pre>
  </div>
  </div>
  </p>
  
  <p>shop-coffee.component.jsx </p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>import React from "react";
  
  export default class ShopCoffee extends React.Component {
   constructor(props) {
    super(props);
    console.log("ShopCoffee /constructor()");
    console.log("ShopCoffee / this.props", this.props);
    this.state = {shopItems : [], itemsInCart : []};
   }
  
  // =============== Добавляет выбранный товар в корзину ===============
   addItemToCart(i) {
    console.log("addItemToCart() i == ",i);
    console.log("addItemToCart() :: this.props", this.props);
    let newSelectedItem = this.state.shopItems[i];
    this.state.itemsInCart.push(newSelectedItem);
    this.props.addNewItemToCart(this.state.itemsInCart);
  
  
   }
  
   getData() {
    const url="/data/coffee.json";
    fetch(url)
     .then((resp) =&gt; resp.json())
     .then((data) =&gt; {
      this.state.shopItems = data;
     })
    .catch((error) =&gt; console.error("Ошибка загрузки данных из файла", url));
    
   }
  
  
   componentWillMount() {
    this.getData();
   }
    componentDidMount() {
          setInterval(() =&gt; this.setState(this.state), 1000);
      }
  
   render() {
    var itemsArr = [];
    var itemsRow = [];
  
    //console.log("this.state.shopItems ===", this.state.shopItems);
    for (let i=0; i &lt; this.state.shopItems.length; i++) {
  
     let item = this.state.shopItems[i];
  
     
     itemsArr.push(
         &lt;div className="shop-coffee__item" key={"item"+i}&gt; 
          &lt;div className="shop-coffee__item__inner"&gt;
           &lt;div className="row"&gt;
            &lt;div className="shop-coffee__item__kg"&gt;
             &lt;p className="shop-coffee__item__kg__text"&gt;{item.weight}&lt;/p&gt;
            &lt;/div&gt;
            &lt;div className="shop-coffee__item__space"&gt;
            &lt;/div&gt;
            &lt;div className="shop-coffee__item__price"&gt;
             &lt;p className="shop-coffee__item__price__text"&gt;{item.price}&lt;/p&gt;
            &lt;/div&gt; 
           &lt;/div&gt; 
           &lt;div className="row"&gt;            
            &lt;div className="shop-coffee__item__image"&gt;
             &lt;img className="shop-coffee__item__image__img" src="img/template-img__coffee-shop.jpg" /&gt;
            &lt;/div&gt;
           &lt;/div&gt;
           &lt;div className="row"&gt;
            &lt;div className="shop-coffee__item__description"&gt;
             &lt;p className="shop-coffee__item__description__text"&gt;
              {item.title}
             &lt;/p&gt;
             &lt;p className="shop-coffee__item__description__text"&gt;
              {item.description}
             &lt;/p&gt;
            &lt;/div&gt;
           &lt;/div&gt;
           &lt;div className="row"&gt;
            &lt;div className="shop-coffee__item__button-container"&gt;
             &lt;button className="shop-coffee__item__button-container__button" onClick={this.addItemToCart.bind(this, i)}&gt;
              Заказать
             &lt;/button&gt;
            &lt;/div&gt;
           &lt;/div&gt;
          &lt;/div&gt;
         &lt;/div&gt; 
     );
     
     if ( ((i&gt;0) &amp;&amp; (i%3 == 0)) || (i == this.state.shopItems.length-1)) {
      itemsRow.push(
         &lt;div className="row" key={"row"+i}&gt;
          {itemsArr}
         &lt;/div&gt;);
      itemsArr = [];
  
     }
  
    }
    return (
      &lt;section className="shop-coffee"&gt;
       &lt;div className="container"&gt;
        &lt;div className="row"&gt;
         &lt;div className="shop-coffee__title-container"&gt;
          &lt;h2 className="shop-coffee__title-container__title"&gt;
           Магазин кофе
          &lt;/h2&gt;
         &lt;/div&gt;
        &lt;/div&gt;
  
      
         {itemsRow}
  
        
       &lt;/div&gt;
      &lt;/section&gt;
    );
   }
  }</code></pre>
  </div>
  </div>
  </p>