在 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