Closed realbugger closed 8 years ago
Although it's working, doesn't it violate the immutable rule of Redux?
Yes, the delete
statement is mutating the previous state. You'll probably find this breaks time travel/undo/redo, which are core benefits of Redux to be ignored at your own peril!
I don't see any code in the example making copies of state object before changing it
That's what ...state
is doing (copying the properties of the previous state to the new object literal that gets returned). It's an ES7 object spread initializer and I believe it does get transpiled down to Object.assign after Babel has its way with it.
Of course, whether deleting the data
property altogether is actually a good idea or not is very debatable. I'd highly recommend rethinking this and keeping your state shapes consistent.
Got it. That makes sense. Thanks a lot.
My google search pointed me here and the answer above seemed vague. How about the following as implementation to removing keys...
It filters the key that should be deleted then builds a new object from the remaining keys and the initial object. The idea is stolen from Tyler McGinnes awesome reactjs program.
function removeByKey (myObj, deleteKey) {
return Object.keys(myObj)
.filter(key => key !== deleteKey)
.reduce((result, current) => {
result[current] = myObj[current];
return result;
}, {});
}
Another solution would be
function removeKey(myObj, deleteKey) {
return Object.assign(
{},
...Object.entries(myObj)
.filter(([k]) => k!== deleteKey)
.map(([k, v]) => ({[k]: v})));
}
Is there something wrong with:
function removeKey(obj, deleteKey) {
let clone = Object.assign({}, obj);
delete clone[deleteKey];
return clone;
}
@Halt001 If you change myObj
parameter to obj
so that function doesn't break, it's perfectly fine :)
You can use destructuring to remove the properties.
Here is a function that I use in my validation reducers to return a valid field state after making sure that the validation passed. It removes the invalid
and error
fields from the given fieldState
object.
function validFieldState(fieldState) {
if (fieldState.invalid) {
const {
invalid: _invalid, // <-- The `_invalid` and `_error` variables are never used.
error: _error,
...nextFieldState, // <-- This variable gets every prop except for `invalid` and `error`.
} = fieldState;
return nextFieldState;
}
return fieldState;
}
This is a common pattern used in React, to remove certain props
before copying them to a child component.
The only headache with your approach @waynebloss, is that a lot of linters do not allow unused variables. You can always disable a rule temporarily, but that kind of inconsistency is not ideal. Especially in a production deployment.
Are there any other approaches besides the ones mentioned here?
@prufrock123 I should have mentioned that the variables should be prefixed with an underscore as shown in my example, because the linter that is built into create-react-app will automatically ignore any unused variable that starts with an underscore.
This seems to be a common feature of other linters and I see it mentioned a few different places:
Couldn't find the official docs for tslint, but it should work.
Which linter are you using?
this code cleans all state variables
let cleanState = {};
Object.keys(this.state).forEach(x => cleanState[x] = null);
this.setState(cleanState);
I don't think that there's anything wrong with that method.
Since the introduction of destructuring and rest syntax to JavaScript, this can now be accomplished in another way:
const { data, ...rest } = state;
return {
...rest,
loading: false,
loaded: false
}
Still learning React JS and Redux, and found this boilerplate to be extremely helpful. Good job Erik!
I'm wondering how to clear/remove a state property, say, state.data. Note that I don't want to just set state.data to null. I want to remove state.data property all together. The following code works for me.
However, my understanding is that state in Redux should not be mutated. Although it's working, doesn't it violate the immutable rule of Redux? Actually, I don't see any code in the example making copies of state object before changing it, like most other Redux implementation does (see below).
So how does the example code get away from the whole Object.assign thing? I must be missing something. Thanks.