PReact useEffect 不会触发状态更改
PReact useEffect doesn't trigger on state change
我想做一个递归函数,基本上每次文件夹下有一个子文件夹时都会运行,这样我就可以从所有可用的子文件夹中获取所有内容。
不确定我在这里遗漏了什么,但是子文件夹的状态更改不会触发将其作为依赖项的 useEffect:
const [imageList, setImageList] = useState([]) as any;
const [subFolders, setSubFolders] = useState([]) as any;
const getFilesFromFolder = (fileId: string) => {
let noToken = false;
const requestFunction = ((pageToken?: string) => {
gapi.client.drive.files.list({
q: `'${fileId}' in parents`,
pageToken
}).execute((res: any) => {
const token = res.nextPageToken && res.nextPageToken || null;
const images = res.files.filter((file: any ) =>
file.mimeType === 'image/jpeg' ||
file.mimeType === 'image/png' ||
file.mimeType === 'image/jpg'
);
setSubFolders([...subFolders, ...res.files.filter((file: any ) => file.mimeType === 'application/vnd.google-apps.folder')]);
setImageList([...imageList, ...images])
if (token) {
requestFunction(token);
} else {
noToken = true;
}
}).catch((err: any) => {
console.log('err', err)
})
});
if (!noToken) {
requestFunction();
}
}
useEffect(() => {
if (subFolders && subFolders.length > 0) {
subFolders.forEach((subFolder: any) => {
getFilesFromFolder(subFolder.id);
});
}
}, [subFolders])
由于您基本上是在遍历文件结构并将状态更新排队,所以我假设您遇到的任何问题都是因为您使用的是正常状态更新。当这些在循环中排队或在渲染周期内多次排队时,它们会覆盖先前排队的更新。
要解决这个问题,您应该真正使用功能状态更新。这样每次更新都会正确地更新前一个状态, 而不是 前一个渲染周期的状态。这是一个微妙但重要的区别,并且经常被忽视。
setSubFolders(subFolders => [
...subFolders,
...res.files.filter((file: any ) =>
file.mimeType === 'application/vnd.google-apps.folder'
),
]);
setImageList(imageList => [...imageList, ...images]);
我想做一个递归函数,基本上每次文件夹下有一个子文件夹时都会运行,这样我就可以从所有可用的子文件夹中获取所有内容。
不确定我在这里遗漏了什么,但是子文件夹的状态更改不会触发将其作为依赖项的 useEffect:
const [imageList, setImageList] = useState([]) as any;
const [subFolders, setSubFolders] = useState([]) as any;
const getFilesFromFolder = (fileId: string) => {
let noToken = false;
const requestFunction = ((pageToken?: string) => {
gapi.client.drive.files.list({
q: `'${fileId}' in parents`,
pageToken
}).execute((res: any) => {
const token = res.nextPageToken && res.nextPageToken || null;
const images = res.files.filter((file: any ) =>
file.mimeType === 'image/jpeg' ||
file.mimeType === 'image/png' ||
file.mimeType === 'image/jpg'
);
setSubFolders([...subFolders, ...res.files.filter((file: any ) => file.mimeType === 'application/vnd.google-apps.folder')]);
setImageList([...imageList, ...images])
if (token) {
requestFunction(token);
} else {
noToken = true;
}
}).catch((err: any) => {
console.log('err', err)
})
});
if (!noToken) {
requestFunction();
}
}
useEffect(() => {
if (subFolders && subFolders.length > 0) {
subFolders.forEach((subFolder: any) => {
getFilesFromFolder(subFolder.id);
});
}
}, [subFolders])
由于您基本上是在遍历文件结构并将状态更新排队,所以我假设您遇到的任何问题都是因为您使用的是正常状态更新。当这些在循环中排队或在渲染周期内多次排队时,它们会覆盖先前排队的更新。
要解决这个问题,您应该真正使用功能状态更新。这样每次更新都会正确地更新前一个状态, 而不是 前一个渲染周期的状态。这是一个微妙但重要的区别,并且经常被忽视。
setSubFolders(subFolders => [
...subFolders,
...res.files.filter((file: any ) =>
file.mimeType === 'application/vnd.google-apps.folder'
),
]);
setImageList(imageList => [...imageList, ...images]);