-
-
Notifications
You must be signed in to change notification settings - Fork 188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
State is saved in past on INIT action #102
Comments
Thanks for reporting this @nivek91, any chance you could post the code causing this? Or the printout of the console with |
To run it The component is Counter Let me know if this helps @pl12133 |
Thanks @nivek91 that was very helpful. It appears that the function handleChangeIncrement(state=1, action) {
switch(action.type) {
case CHANGE_INC:
return +action.value;
default:
return state;
}
}
function handleCounter(state=0, action, incrementValue) {
switch(action.type) {
case INC:
return state + incrementValue;
default:
return state;
}
}
function counter(state = {}, action) {
let incrementValue = handleChangeIncrement(state.incrementValue, action);
let counterValue = handleCounter(state.counterValue, action, incrementValue); // note: b depends on a for computation
return { incrementValue, counterValue };
} Because you use { incrementValue: 1, counterValue: 0 } === { incrementValue: 1, counterValue: 0 } // false Redux-undo expects all the contracts of a valid Redux reducer to hold true, so this is not related to |
Thanks for answering this quickly @pl12133 . I'm creating the reducers this way based on this: @gaearon reduxjs/redux#749 (comment) This is the snipped: function something(state = {}, action) { Am I doing something wrong, or the snippet is wrong? Lots of thanks! |
The snippet is right, but it was a demonstration of a selector (something to retrieve data), not a reducer. |
How would write a reducer that depends on other reducer's state? |
That's quite a general question, which makes it hard to answer. I would recommend documentation on reducer composition, it's mentioned in the reducer docs and in some talks of: https://egghead.io/courses/getting-started-with-redux In your case using combineReducers might help. |
I'm already using combineReducers. Can you show with my example how would you do it? |
I haven't tried this out, but generally you just add extra information onto the function handleChangeIncrement(state=1, action) {
switch(action.type) {
case CHANGE_INC:
return +action.value;
default:
return state;
}
}
function handleCounter(state=0, action) {
switch(action.type) {
case INC:
let { incrementValue } = action;
return state + incrementValue;
default:
return state;
}
}
function counter(state = {}, action) {
let incrementValue = handleChangeIncrement(state.incrementValue, action);
state = handleCounter(state.counterValue, {
type: action.type,
incrementValue
};
return state;
} With this reducer, passing in a probe action will not return a new state. |
Hi @pl12133 , first, thanks for answering! I just tested the code you posted (there was a missing ')' ), and now my initial state is being ignored: Any other ideas? |
I'm not sure I see the issue there, the reducer seems to be working as expected. After |
Hi! @pl12133 , its not working because the initial state should be: Thanks for taking the time |
Sure, if you would like to shape your state that way then you can have your functions do that. If you are just getting in to Redux I would recommend the Egghead.io tutorials to learn about creating your own reducers. Here is the code from above combined into one reducer: const initialState = {
incrementValue: 1,
counterValue: 0
};
function counter(state = initialState, action) {
switch(action.type) {
case CHANGE_INC:
return Object.assign({}, state, {
incrementValue: +action.value
})
case INC:
return Object.assign({}, state, {
counterValue: state.counterValue + state.incrementValue
})
default:
return state;
}
} |
Thats what I was trying to do, but I wanted to split the logic into 2 reducers (or sub reducers), one depending on the other one. It seems that splitting them is not possible? I already watched those tutorials, but they dont show how to share state (using different reducers) |
That may be possible, but it does not seem like a good idea for one reducer to rely upon another because that is creating a side effect. Avoiding side effects is good because it makes a Redux reducer very easy to reason about. Here is what the doc's say about it:
If your reducer needs some extra data, you can pass it in on the |
Hi, I was trying to reproduce the example of todos-undo, using beta 8, when I came across this bug.
After init, the state is modified (in the past object there is a copy of the state), so when I was doing,
canUndo: state.todos.past.length > 0,
you could start the app by undoing.
Then I switched to beta 2, and this changed:
The past object is empty after INIT.
So this should be documented? Or the example should be updated to use beta8?
Thanks
The text was updated successfully, but these errors were encountered: