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