0
votes

I have implemented a simple counter reducer with actions like 'increment', 'decrement' and so on. I have 'save' action that is supposed to save current counter value in array.

I have also implemented another reducer that is supposed to fetch some data on load and save it to an array.

When I dispatch 'save' action to counter reducer Redux Dev tool state chart shows that fetch reducer is also updating. It is not changing any values of fetch reducer but chart shows strange behaviour.

I probably have a misstake into how I am using the fetch reducer or both.

App.js (container component)

    import React, { Component } from 'react';
    import { connect } from 'react-redux'
    import logo from './logo.svg';
    import './App.css';
    import Counter from './components/Counter'
    import Data from './components/Data'
    import {
      increaseAction,
      decreaseAction,
      resetAction,
      saveAction,
      removeAction,
      fetchData
    } from './actions'

    class App extends Component {
      componentDidMount() {
        // the only thing i dispatch to fetch reducer
        const response = [1,2,3,4,5,6,7,8]
        this.props.fetchData(response);
      }
      render() {
        return (
          <div className="App">
            <div className="App-header">
              <img src={logo} className="App-logo" alt="logo" />
              <h2>Welcome to React</h2>
            </div>
            <p className="App-intro">
              To get started, edit <code>src/App.js</code> and save to reload.
            </p>
            <Counter
              onIncreaseClick={this.props.onIncreaseClick}
              onDecreaseClick={this.props.onDecreaseClick}
              onResetClick={this.props.onResetClick}
              onSaveClick={this.props.onSaveClick}
              onRemoveClick={this.props.onRemoveClick}
              value={this.props.counterValue}
              savedCounter={this.props.savedCounter}
            />
            <Data data={this.props.fetch}/>
          </div>
        );
      }
    }

  // Map Redux state to component props
  function mapStateToProps(state)  {
    let counter = state.counter
    let fetch = state.fetch
    return {
      counterValue: counter.count,
      savedCounter: counter.saved,
      fetch: fetch.data
    };
  }

  // Map Redux actions to component props
  function mapDispatchToProps(dispatch) {
    return {
      onIncreaseClick: () => dispatch(increaseAction),
      onDecreaseClick: () => dispatch(decreaseAction),
      onResetClick: () => dispatch(resetAction),
      onSaveClick: () => dispatch(saveAction),
      onRemoveClick: () => dispatch(removeAction),
      fetchData: (data) => dispatch(fetchData(data))
    };
  }

  export default connect(mapStateToProps, mapDispatchToProps)(App)

Here are my reducers(they are in separate files)

    // Reducer:
    function counter(state={count: 0, saved: []}, action) {
      let count = state.count;
      let saved = state.saved;
      switch(action.type){
        case 'increase':
          return {
            ...state,
            count: count  + 1
          };
        case 'decrease':
          if (count === 0) {
            return {...state, count: count }
          }
          return {
            ...state,
            count: count - 1
          };
        case 'reset':
          return {
            ...state,
            count: count  = 0
          };
        case 'save':
          return {
            ...state,
            saved: [...saved, count]
          };
        case 'remove':
          return {
            ...state,
            saved: [...saved.slice(0, -1)]
          };
        default:
          return state;
      }
    }

    export default counter

    // Reducer:
    function fetch(state={data: []}, action) {
      console.log("When I call 'save' this is also invoked");
      switch(action.type){
        case 'fetch':
        return {...state, data: [...action.payload] }
        default:
          return state;
      }
    }

    export default fetch

Actions:

    export const increaseAction = {type: 'increase'};
    export const decreaseAction = {type: 'decrease'};
    export const resetAction = {type: 'reset'};
    export const saveAction = {type: 'save'};
    export const removeAction = {type: 'remove'};
    export const FETCH_DATA = 'fetch';

    export function fetchData(payload) {
      return {
        type: FETCH_DATA,
        payload: payload,
      }
    }

How I create my store(note this logic is all situated in index.js for simplicity):

    // Combine all application reducers
    const appStore = combineReducers({
      counter,
      fetch
    })


    // Store configuration
    const loggerMiddleware = createLogger()
    let store = createStore(
      appStore,
      // only for dev
      window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(),
      applyMiddleware(
        loggerMiddleware
      )
    )

See what's the problem in a video: https://youtu.be/oKOkU_VjZ7E

Try it out: https://github.com/kdichev/personal-portfolio/tree/feature/add-create-redux-react-app

1

1 Answers

1
votes

All reducers get called when you dispatch any action, that is by design.