admin管理员组文章数量:1315959
If I have pletely replacing the entirety of a slice of state, do I still have to use Object.assign or the spread operator to make a copy of the original state and replace it with the new state, or can I just return the new state in my reducer?
const fetching = (state = { isFetching: false }, action) => {
switch (action.type) {
case 'REQUESTING':
return Object.assign({}, state, { isFetching: true } )
case 'RECEIVE_POKEMON_TYPE_INFO':
return Object.assign({}, state, { isFetching: false } )
default:
return state
}
}
vs.
const fetching = (state = { isFetching: false }, action) => {
switch (action.type) {
case 'REQUESTING':
return { isFetching: true }
case 'RECEIVE_POKEMON_TYPE_INFO':
return { isFetching: false }
default:
return state
}
}
If I have pletely replacing the entirety of a slice of state, do I still have to use Object.assign or the spread operator to make a copy of the original state and replace it with the new state, or can I just return the new state in my reducer?
const fetching = (state = { isFetching: false }, action) => {
switch (action.type) {
case 'REQUESTING':
return Object.assign({}, state, { isFetching: true } )
case 'RECEIVE_POKEMON_TYPE_INFO':
return Object.assign({}, state, { isFetching: false } )
default:
return state
}
}
vs.
const fetching = (state = { isFetching: false }, action) => {
switch (action.type) {
case 'REQUESTING':
return { isFetching: true }
case 'RECEIVE_POKEMON_TYPE_INFO':
return { isFetching: false }
default:
return state
}
}
Share
Improve this question
asked Aug 29, 2016 at 6:55
mangocaptainmangocaptain
1,4951 gold badge20 silver badges32 bronze badges
3
-
If you can replace
return Object.assign({}, state, { isFetching: true } )
withreturn Object.assign({}, { isFetching: true } )
, then you can replace it with{ isFetching: true }
. Otherwise, you cannot because rest of state will be lost. – Pandaiolo Commented Aug 29, 2016 at 16:07 - I think there's a similar question has been answered here – Bryan Tung Commented May 8, 2017 at 18:06
- I think there's a similar question has been answered here. – Bryan Tung Commented May 8, 2017 at 18:09
2 Answers
Reset to default 6There are a couple of things going on here. Basically, if your state only consists of a boolean variable, then creating a new object by enumeration is OK. However, if your state consists of other things, then doing an object.assign should work.
However (and isn't there always a 'however'), if your state is plex - that is it consists of other objects then doing object.assign will not properly copy the fields - it copied the references not the values. For example, if your state consists of a "currentlySelectedPokemon" field there the value is a Pokemon object, then Object.assign will copy a reference to the pokemon object. It won't copy the object itself. To show this more easily, look at the code below - it prints "value2" for obj2.
var obj1 = {
field: {
subfield: "value"
}
};
var obj2 = Object.assign({}, obj1);
obj1.field.subfield = "value2";
console.log(JSON.stringify(obj2, null, 2));
There are two ways to get around this. The first is to use the Immutable library for all your state. However, I found the overhead of converting plex objects into Immutable and back provided enough plexity that it introduced unnecessary bugs. So now I do this:
const fetching = (state = { isFetching: false }, action) => {
switch (action.type) {
case 'REQUESTING':
const newState = JSON.parse(JSON.stringify(state));
newState.isFetching = true;
return newState;
case 'RECEIVE_POKEMON_TYPE_INFO':
const newState = JSON.parse(JSON.stringify(state));
newState.isFetching = false;
return newState;
default:
return state
}
}
It turns out that JSON.parse(JSON.stringify(object)) is a fast reliable way to make a copy of a vanilla java object. It strips all functions (which is what I generally want). And it's fast because browsers usually implement those functions in native code.
you can either use Object.assign
or spread operator
, like below
using Object.assign
:
const fetching = (state = { isFetching: false }, action) => {
switch (action.type) {
case 'REQUESTING':
return Object.assign({}, state, { isFetching: true } )
case 'RECEIVE_POKEMON_TYPE_INFO':
return Object.assign({}, state, { isFetching: false } )
default:
return state
}
}
using spread operator:
const fetching = (state = { isFetching: false }, action) => {
switch (action.type) {
case 'REQUESTING':
return { ...state, isFetching: true }
case 'RECEIVE_POKEMON_TYPE_INFO':
return { ...state, isFetching: false }
default:
return state
}
}
using Object.assign()
can quickly make simple reducers difficult to read given its rather verbose syntax
.the spread (...)
operator to copy enumerable properties from one object to another in a more succinct way.
本文标签: javascriptReplacing new state in react redux reducer without making a copyStack Overflow
版权声明:本文标题:javascript - Replacing new state in react redux reducer without making a copy - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741983217a2408522.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论