0

When I press the button increment or decrement, I get this message. I think all the steps are okay but I can not understand why, when I press the button (+ or -), the store/state is set to undefined;

src/App.js

 import React, { Component } from "react";
    import Counter from "./components/counter";
    import { connect } from "react-redux";

    class App extends Component {
      render() {
        return (
          <div>
            {this.props.data.map(counter => (
              <Counter key={counter.id} id={counter.id} value={counter.value} />
            ))}
          </div>
        );
      }
    }

    const mapStateToProps = state => {
      return {
        data: state.data
      };
    };
    export default connect(mapStateToProps)(App);

src/components/counter.js

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

class Counter extends Component {
  render() {
    return (
      <div>
        <h1>{this.props.value}</h1>
        <button onClick={() => this.props.onIcrement(this.props.id)}>
          + UP
        </button>
        <button onClick={() => this.props.onDecrement(this.props.id)}>
          - DOWN
        </button>
      </div>
    );
  }
}

const mapDispatchToProps = dispatch => {
  return {
    onIcrement: id => dispatch({ type: "INCREMENT", key: id }),
    onDecrement: id => dispatch({ type: "DECREMENT", key: id })
  };
};

export default connect(
  null,
  mapDispatchToProps
)(Counter);       

src/store/reducer.js

const initialState = {
  data: [{ id: 1, value: 4 }, { id: 2, value: 0 }]
};
const reducer = (state = initialState, action) => {
  const newState = { ...state };
  switch (action.type) {
    case "INCREMENT":
      return newState.data.map(el => {
        if (action.key === el.id) {
          return el.value++;
        }
        return el.value;
      });
    case "DECREMENT":
      return newState.data.map(el => {
        if (action.key === el.id) {
          return el.value--;
        }
        return el.value;
      });
    default:
      return newState;
  }
};
export default reducer;

src/index.js

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import { createStore } from "redux";
import { Provider } from "react-redux";
import reducer from "./store/reducer";

const store = createStore(reducer);

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


serviceWorker.unregister();

................................................................................

1 Answer 1

2

In your reducer, you are returning an array instead of an object with a key data which is an array.

The following code should work.

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case "INCREMENT":
      return {
        data: state.data.map(el => { // <- return object with data instead of newState.data.map
          if (action.key === el.id) {
            return { ...el, value: el.value + 1};
          }
          return el;
        })
      };
    case "DECREMENT":
      return {
        data: state.data.map(el => { // <- same here too 
          if (action.key === el.id) {
            return { ...el, value: el.value - 1 };
          }
          return el;
        })
      };
    default:
      return state;
  }
};
Sign up to request clarification or add additional context in comments.

1 Comment

I tried but when i pressed the (+/-) i got this [1] and after when i pressed again the button i got this [2]... [1]: i.sstatic.net/E8bFw.png [2]: i.sstatic.net/gyYwA.png

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.