Fabian Andiel
Fabian Andiel

Reputation: 331

MapStateToProps and MapDispachToProps in parent and child components not working

Within my app.js I have my mapDispachToProps function ,which is supposed to send an action of type:increment to the reducer in the redux store. When the reducer receives it he is supposed to incremnet the initial state by 1.

In the heading component, which is a child of the app.js component I want to display the new value via mapStateToProps and this.props.value. The problem is it doesn`t work and I get no error message in the console.

When I do everything in the App.js it works very well.

What am I doing wrong?

Thanks in advance

My index.js

let store = createStore(increaseReducer);

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

My store

export function increaseReducer(state = 0, action) {
    if(action.type == "INCREMENT") {
        return state+1;
    }   

    else {
        return state;
    }
}
export default increaseReducer;

my app.js

import React, {Component} from 'react';
import{ connect }from 'react-redux';
import {Heading} from './components/heading';

class App extends Component {
  constructor(props) {
    super(props);
  }
  render() {
  return (
    <div className="App">
       <Heading></Heading>
       <button onClick={this.props.increment} > Counter</button>
    </div>
  );
  }
}

let mapDispachToProps= {
  increment:()=> {
  return {type:"INCREMENT"}}
}

let AppContainer= connect(null,mapDispachToProps)(App);
export default AppContainer;

my heading.js

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

export class Heading extends Component {
        constructor(props){
            super(props);
        }

        render() {
            return(
                    <h1>Click Counter: {this.props.value}  </h1>    
                )
        }
}

let mapStateToProps = (state)=>{return {
  value: state
}}

let headingContainer = connect(mapStateToProps)(Heading);

export default headingContainer;

Upvotes: 3

Views: 852

Answers (2)

HMR
HMR

Reputation: 39270

Heading exports default so in App it should be:

import Heading from './components/heading';

Here is your code as a snippet and it works:

const {
  Provider,
  connect,
} = ReactRedux;
const { createStore } = Redux;
const { Component } = React;

function increaseReducer(state = 0, action) {
  if (action.type == 'INCREMENT') {
    return state + 1;
  } else {
    return state;
  }
}
let store = createStore(increaseReducer);

//heading
class HeadingComponent extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return <h1>Click Counter: {this.props.value} </h1>;
  }
}

let mapStateToProps = (state) => {
  return {
    value: state,
  };
};

let Heading = connect(mapStateToProps)(HeadingComponent);

class App extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div className="App">
        <Heading></Heading>
        <button onClick={this.props.increment}>
          {' '}
          Counter
        </button>
      </div>
    );
  }
}

let mapDispachToProps = {
  increment: () => {
    return { type: 'INCREMENT' };
  },
};

let AppContainer = connect(null, mapDispachToProps)(App);

ReactDOM.render(
  <Provider store={store}>
    <AppContainer />
  </Provider>,
  document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script>


<div id="root"></div>

Upvotes: 2

demkovych
demkovych

Reputation: 8837

You need to dispatch your actions:


const mapDispachToProps = dispatch => {
  return {
    increment: () => dispatch({
      type:"INCREMENT"
    }}
  }
}

reducer:

export default (state = 0, action) => {
    switch (action.type) {
      case 'INCREMENT':
        return state + 1;
      default:
        return state;
    }

Upvotes: 1

Related Questions