Reputation: 6289
In my React project I have a function within a class-based component that handles video uploads. It is working as expected and desired. However, I realized upon inspection that it violates React's don't mutate state mandate. I think that's the case, though I want to ensure that's true, and that the solution I've come up with deals with this.
Here is my component state:
state = {
streamingRes: {},
uploadFailed: false
}
My initial function looked like this (notice there are 3 places where I am setting the state):
fileUploadHandler = (id, file, fileId) => {
const isValid = this.validateVideoFileType(file);
if(!isValid) this.props.showError(`${file.name} is of the wrong file type (${file.type}). File must be an acceptable video format.`);
let dataStream = io.Stream.createStream();
io.Socket.on('userVideos.uploadProgress', (data) => {
this.setState( { streamingRes: data });
if(fileId === data.data.guid) {
this.uploadCompletionPercentage = data.data.progress;
}
});
io.Stream(io.Socket).emit('userVideos.upload', dataStream, {
guid: fileId,
size: file.size
}, (data) => {
if(data.status === "failure") {
this.props.onUploadFailed();
this.setState( { uploadFailed: true })
}
else if(data.status === "success") {
this.props.upload(id)
}
});
this.setState( { uploadFailed: false });
io.Stream.createBlobReadStream(file).pipe(dataStream);
return;
}
To avoid mutating state I updated this function to look like this:
handleFileUpload = (id, file, fileId) => {
let newState = {...this.state};
const isValid = this.validateVideoFileType(file);
if(!isValid) this.props.showError(`${file.name} is of the wrong file type (${file.type}). File must be an acceptable video format.`);
let dataStream = io.Stream.createStream();
io.Socket.on('userVideos.uploadProgress', (data) => {
this.setState( { streamingRes: data });
if(fileId === data.data.guid) {
this.uploadCompletionPercentage = data.data.progress;
}
});
io.Stream(io.Socket).emit('userVideos.upload', dataStream, {
guid: fileId,
size: file.size
}, (data) => {
if(data.status === "failure") {
this.props.onUploadFailed();
newState.uploadFailed = true;
this.setState( { uploadFailed: newState.uploadFailed });
}
else if(data.status === "success") {
this.props.upload(id)
}
});
newState.uploadFailed = false;
this.setState( { uploadFailed: newState.uploadFailed });
io.Stream.createBlobReadStream(file).pipe(dataStream);
return;
}
Notice I am using the spread operator right at the top of the function now. My question is: does this effectively deal with the issue of avoiding state mutation?
Upvotes: 0
Views: 210
Reputation: 130102
Yes, you have avoided mutating state. However, your way of doing it is completely unnecessary because there is no need to copy the state into a new object if you don't use that object.
Instead of:
newState.uploadFailed = true;
this.setState( { uploadFailed: newState.uploadFailed });
You can simply do:
this.setState({ uploadFailed: false });
There was no problem in your code in the first place.
Upvotes: 1