如何在不排除某些依赖项的情况下使React useEffect挂钩工作



我创建了一个condesandbox,在这里重新创建了这个问题:https://codesandbox.io/s/agitated-tree-dq8rx?file=/src/App.js

沙箱重新创建了一个组件的功能,该组件显示了可以选择的空图像预览缩略图列表。

当用户上传图像并且返回downloadUrl时,更新当前选择的图像的图像缩略图。useEffect挂钩依赖于downloadUrl,因此每次上传新图像并返回downloadUrl时都会调用它。我用一个按钮模仿了这个功能,每次点击它都会返回一个新的URL。

如果我包含了依赖项的完整列表,downloadUrl会立即应用于单击的下一个区域。这不是我想要的。我希望能够选择下一个图像缩略图并为其分配不同的downloadUrl。只有当我排除了"project"one_answers"selectedZoneIndex"依赖项时,这才能正常工作。

我试图通过使用useReducer钩子和调度函数来解决这个问题。这成功地删除了依赖项,但是调度函数的结果在useEffect钩子中不可用,所以我不能使用新对象来更新项目。我在这里举了一个例子:https://codesandbox.io/s/jovial-sara-ofoh1?file=/src/App.js(控制台中的newProject为undefined(

如果您能就如何在遵循最佳实践(不排除应包含的依赖项(的同时解决此问题提供任何建议,我将不胜感激。

useEffect(() => {
const onUpdateProject = async (newProject) => {
try {
await updateDatabase(newProject)
return "updated"
} catch (error) {
return "error"
}
}
if (downloadUrl) {
setSelectedZoneImageUrl(downloadUrl);
// Update Zone with downloadUrl
const updatedZones = zones.slice();
updatedZones[selectedZoneIndex]["imageDownloadUrl"] = downloadUrl;
// Create new project with updated zone
const newProject = {
...project,
zones: updatedZones,
};
onUpdateProject(newProject);
}
}, [downloadUrl, selectedZoneIndex, project, zones])

据我所知,您根本不需要useEffect。也许您的实际用例使这不可行,但如果您消除了这种影响并将所有逻辑放入newDownloadUrl处理程序中,那么您的原始代码示例似乎可以按预期工作。如果一切都发生在同一个地方,就没有必要对状态的变化做出反应。

我还发现了处理zones数组的另一个问题——因为它是一个对象数组,所以需要单独克隆每个对象,否则它们将保留引用。在updateDatabase:中调用setter之前,您的状态正在发生变化

const newDownloadUrl = () => {
const onUpdateProject = async newProject => {
try {
await updateDatabase(newProject);
return "updated";
} catch (error) {
return "error";
}
};
const newUrl = "www." + Math.round(Math.random() * 100) + ".com";
setDownloadUrl(newUrl);
setSelectedZoneImageUrl(newUrl);
// Update Zone with downloadUrl
const updatedZones = zones.slice().map(z => ({...z}));
updatedZones[selectedZoneIndex]["imageDownloadUrl"] = newUrl;
// Create new project with updated zone
const newProject = {
...project,
zones: updatedZones
};
onUpdateProject(newProject);
};

相关内容

  • 没有找到相关文章