Reputation: 1454
i'm new in Redux.I have a problem, i make a simple Redux app with two different functionality one is increment decrement on the base of count and second is Click on button then image change, so that my real problem is when i update the state increment decrement first then working good but if i press the button click then again press to increment or decrement button then show me Error NAN in the place of increment decrement result 1 2 0r other And in the console show me bellow error:
Received NaN for the `children` attribute. If this is expected, cast the value to a string.
“I try many ways like dispatch the action many different ways but not working in any case for me.”
please check the code and guide me
constants.js
export const CLICK_ME = 'CLICK_ME'
export const INCREMENT = 'INCREMENT'
export const DECREMENT = 'DECREMENT'
action.js
import {CLICK_ME, INCREMENT, DECREMENT} from '../constant/constant'
export const clicking = () => {
return {
type:CLICK_ME
}
}
export const increment =()=>{
return {
type : INCREMENT
}
}
export const decrement =()=>{
return {
type : DECREMENT
}
}
reducer.js
import {CLICK_ME, INCREMENT, DECREMENT} from '../constant/constant'
const initialState = {
click : true,
count: 0
}
const reducer = (state = initialState , action) => {
if(action.type === CLICK_ME){
return {click : !state.click}
}
else if(action.type === INCREMENT ){
return { count: state.count + 1 }
}
else if(action.type === DECREMENT ){
return { count: state.count - 1 }
}
else return state
}
export default reducer
store.js
import reducer from '../reducers/reducer'
import { createStore } from 'redux'
const store = createStore(reducer)
export default store
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import 'bootstrap/dist/css/bootstrap.css'
import store from './store/store'
import { Provider } from 'react-redux'
ReactDOM.render(
<Provider store={store} >
<App />
</Provider>
, document.getElementById('root'));
serviceWorker.unregister();
App.js
import React from 'react';
import {connect} from 'react-redux'
import { CLICK_ME, INCREMENT, DECREMENT } from './constant/constant';
function App(props) {
return (
<div className="container pt-5 mt-5 ">
<div className="row">
<div className="col col-sm-8 col-md-8 col-lg-8 col-xl-8 ">
{ props.click ? <img src="data:image/jpeg;base64,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" className="img-fluid rounded-circle" width="30%" height="auto" alt=""/> : <img src="https://cdn2.iconfinder.com/data/icons/user-needs-19/16/45_false_delete_remove_cross_wrong_2-512.png" className="img-fluid rounded-circle" alt="" width="30%" height="auto" />}
</div>
<div className="col col-sm-4 col-md-4 col-lg-4 col-xl-4 ">
<p className="text-danger" >THE NUMBER IS COUNT ON EVERY CLICK </p>
<code className="p-5 " style={{fontSize:"100px"}} >{props.count}</code>
</div>
</div>
<hr className="bg-info p-1 m-1" />
<button className="btn btn-danger m-1" onClick={props.increment} >Increment</button>
<button className="btn btn-danger m-1" onClick={props.decrement} >Decrement</button>
<button className="btn btn-primary bg-info float-right" onClick={props.clicks} >Click me to change the state</button>
</div>
);
}
const mapStateToProps = (state)=>{
return {
click : state.click,
count : state.count
}
}
const dispatchToProps = (dispatch) => {
return {
clicks:()=>dispatch({type:CLICK_ME}),
increment :()=>dispatch({type:INCREMENT}),
decrement :()=>dispatch({type:DECREMENT})
}
}
export default connect(mapStateToProps,dispatchToProps)(App)
Upvotes: 2
Views: 441
Reputation: 2655
Your problem is inside the reducer, when you are dispatching the actions and updating the redux store, you are returning the updated state, only the field that you want to update not the previous values from the state and the updated field plus value.
const reducer = (state = initialState , action) => {
if(action.type === CLICK_ME){
return {
...state,
click : !state.click
}
}
else if(action.type === INCREMENT ){
return {
...state,
count: state.count + 1
}
}
else if(action.type === DECREMENT ){
return {
...state,
count: state.count - 1
}
}
else return state
}
I would recommend this way of writing a reducer: Is this redux reducer OK
Upvotes: 1
Reputation: 38121
The key thing you are missing is that you need to return the whole state from your reducer function, not just the piece you modified with that action. That means copying over the properties you didn't modify.
Change your reducer function as follows (and I also suggest you use a switch
statement, it's less typing and consistent with other Redux code):
import {CLICK_ME, INCREMENT, DECREMENT} from '../constant/constant'
const initialState = {
click : true,
count: 0
}
const reducer = (state = initialState , action) => {
switch (action.type) {
case CLICK_ME:
return { ...state, click: !state.click };
case INCREMENT:
return { ...state, count: state.count + 1 };
case DECREMENT:
return { ...state, count: state.count - 1 };
default:
return state;
}
}
export default reducer;
In case you are not familiar with it, the ...state
is using the object spread operator, which copies all the properties and their values from state
onto the new object. Alternatively, you can use the equivalent Object.assign({}, state, { modified: 'state' })
.
Upvotes: 1