使用扩展运算符避免 React 函数中的状态改变

Using spread operator to avoid mutating state in React function

在我的 React 项目中,我在基于 class 的组件中有一个函数可以处理视频上传。它正在按预期和期望工作。然而,我在检查后意识到它违反了 React 的 don't mutate state mandate。我认为是这样,但我想确保这是真的,而且我想出的解决方案可以解决这个问题。

这是我的组件状态:

  state = {
    streamingRes: {},
    uploadFailed: false
  }

我的初始函数如下所示(注意我在 3 个地方设置状态):

  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;
  }

为了避免改变状态,我将此函数更新为如下所示:

  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;
  }

注意我现在在函数的顶部使用展开运算符。我的问题是:这是否有效地解决了避免状态突变的问题?

是的,您避免了变异状态。但是,您这样做是完全没有必要的,因为如果您不使用该对象,则无需将状态复制到新对象中。

而不是:

newState.uploadFailed = true;
this.setState( { uploadFailed: newState.uploadFailed });

你可以简单地做:

this.setState({ uploadFailed: false });

首先你的代码没有问题。