开发者问题收集

在 React 中的递归函数中更新类的状态

2021-05-20
778

我对 reactjs 还很陌生。目前,我正在开发一个需要迭代读取一些文件的项目。因此,我将一些文件传递给 fileHandlingFunction

export class MainComponent extends React.Component {
  constructor(){
    this.state = {
      imageFiles: [];
    }
  }

  fileHandlingFunction(files){ // files is an array of image files
    // iterate through the files and append them into an array in state
    this.syncIterate(files, this.syncIterate);
  }

  syncIterate(fileArray, callBackSyncIterate) {
    let tempFile = fileArray[0];
    const reader = new FileReader();
    reader.readAsDataURL(tempFile);
    reader.onload = (event) => {
      this.setState({imageFiles: this.state.imageFiles.concat[reader.result]});
    }

    if (fileArray.length > 1) {
      // Removes the first element of the file array
      let updatedArray = fileArray.slice(1);
      callBackSyncIterate(updatedArray, callBackSyncIterate);
    }
  }
}

当我使用 for 循环将文件附加到状态中时,较小的文件会先附加,然后较大的文件会附加(我绝对需要避免这种情况)。这就是以递归方式使用回调函数来迭代传递给 fileHandlingFunction files 数组的原因。

但是,当我尝试在递归函数调用中插入图像文件时,我收到 “Uncaught TypeError:无法读取未定义的属性‘setState’” 错误。 在这个阶段,我们无法在递归函数调用中更改组件的状态。我希望您的建议能够解决此问题。 非常感谢您帮助我解决此问题。提前致谢。

2个回答

将该方法回调到 onload 中:

function fileHandlingFunction(files) { // files is an array of image files
    // iterate through the files and append them into an array in state
    let stateArray = [];
    this.syncIterate(files, stateArray, this.syncIterate);
    this.setState({imageFiles: stateArray});
}

function syncIterate(fileArray, stateArray, callBackSyncIterate) {
    let tempFile = fileArray[0];
    const reader = new FileReader();
    reader.readAsDataURL(tempFile);
    reader.onload = (event) => {
        stateArray.push(reader.result);
        if (fileArray.length > 1) {
            // Removes the first element of the file array
            let updatedArray = fileArray.slice(1);
            callBackSyncIterate(updatedArray, callBackSyncIterate);
        }
    }
}
Raul Licaret
2021-05-20

reader.onLoad 为函数本身创建一个新的 javascript 上下文(因此使用了箭头函数)。 因此,您使用的 onload 函数中的“this”仅与函数上下文相关。 尝试添加一个变量,在其中存储类/组件的上下文。 例如 let that = this

export class MainComponent extends React.Component {
  constructor(){
    this.state = {
      imageFiles: [];
    }
  }

  fileHandlingFunction(files){ // files is an array of image files
    // iterate through the files and append them into an array in state
    this.syncIterate(files, this.syncIterate);
  }

  syncIterate(fileArray, callBackSyncIterate) {
    let that = this;
    let tempFile = fileArray[0];
    const reader = new FileReader();
    reader.readAsDataURL(tempFile);
    reader.onload = (event) => {
      that.setState({imageFiles: that.state.imageFiles.concat[reader.result]});
    }

    if (fileArray.length > 1) {
      // Removes the first element of the file array
      let updatedArray = fileArray.slice(1);
      callBackSyncIterate(updatedArray, callBackSyncIterate);
    }
  }
}
David V
2021-05-20