Reactjs 使用扩展算子避免React函数中的状态突变

Reactjs 使用扩展算子避免React函数中的状态突变,reactjs,setstate,react-state-management,Reactjs,Setstate,React State Management,在我的React项目中,我在一个基于类的组件中有一个函数,用于处理视频上传。它正在按预期和期望工作。然而,经过检查,我意识到这违反了React的“不变异”国家规定。我认为情况就是这样,尽管我想确保这是真的,而且我提出的解决方案解决了这个问题 以下是我的组件状态: state = { streamingRes: {}, uploadFailed: false } 我的初始函数如下所示(注意,我在3个地方设置状态): 为了避免状态发生变化,我将此函数更新为如下所示: h

在我的React项目中,我在一个基于类的组件中有一个函数,用于处理视频上传。它正在按预期和期望工作。然而,经过检查,我意识到这违反了React的“不变异”国家规定。我认为情况就是这样,尽管我想确保这是真的,而且我提出的解决方案解决了这个问题

以下是我的组件状态:

  state = {
    streamingRes: {},
    uploadFailed: false
  }
我的初始函数如下所示(注意,我在3个地方设置状态):

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

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

请注意,我现在正在函数顶部使用spread操作符。我的问题是:这是否有效地解决了避免状态突变的问题?

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

而不是:

newState.uploadFailed = true;
this.setState( { uploadFailed: newState.uploadFailed });
您可以简单地执行以下操作:

this.setState({ uploadFailed: false });

您的代码一开始就没有问题。

那么您是说我的初始实现没有改变状态?@Muirik一点也没有。例如,变异状态将是
this.state.uploadFailed=false
。当您的状态包含对象而非简单值时,通常会出现变异状态的问题,例如,如果您尝试在不首先复制值的情况下变异
progressResponse
。@Muirik如果发现问题更大的是
这个。uploadCompletionPercentage
,它显然会在不使用道具状态的情况下以某种方式变异组件。是的,我现在明白了。那是因为我误解了变异国家的问题。我会相应地更新。
this.setState({ uploadFailed: false });