一般来说,在一个组件中使用一个还是多个useEffect钩子更好?

我有一些副作用应用在我的反应组件,想知道如何组织他们:

  • 作为一个单独的useEffect
  • 或几个useEffects

在性能和架构方面,哪个更好?

186220 次浏览

您需要遵循的模式取决于您的用例。

你可能会遇到这样的情况:你需要在初始挂载期间添加事件侦听器,并在卸载时清理它们;另一种情况是,特定的侦听器需要在道具更改时清理并重新添加。

在这种情况下,使用两个不同的useEffect可以更好地将相关逻辑放在一起,并提高性能

useEffect(() => {
// adding event listeners on mount here
return () => {
// cleaning up the listeners here
}
}, []);


useEffect(() => {
// adding listeners everytime props.x changes
return () => {
// removing the listener when props.x changes
}
}, [props.x])

当任何状态或道具从定义的集合中改变时,你需要触发API调用或其他副作用。在这种情况下,使用单独的useEffect来监视相关的依赖关系会更好

useEffect(() => {
// side effect here on change of any of props.x or stateY
}, [props.x, stateY])

你需要为不同的变化集单独的副作用。在这种情况下,将相关的副作用分离到不同的__abc中

useEffect(() => {
// some side-effect on change of props.x
}, [props.x])


useEffect(() => {
// another side-effect on change of stateX or stateY
}, [stateX, stateY])

你应该使用多个效果单独的问题作为由reactjs.org建议

它是完美的有多个useEffect。

以下是我的其中一个设置:

/*
* Backend tags list have changed add the changes if needed
*/
useEffect(() => {
setTagsList(setTagsAdded);
}, [setTagsAdded]);


/*
* Backend files have changed add the changes if needed
*/
useEffect(() => {
for (let i = 0; i < changedFilesMeta.length; i += 1) {
// Is the list item value changed
if (changedFilesMeta[i].id === currentEditableFile.id) {
unstable_batchedUpdates(() => {
setTags(changedFilesMeta[i].tags ? changedFilesMeta[i].tags : []);
});
}
}
}, [changedFilesMeta]);


/*
* Reset when user select new files using the filepicker
*/
useEffect(() => {
if (setNewFiles.length > 0) {
unstable_batchedUpdates(() => {
setCurrentFile(null);
setDescription('');
setTitle('');
setTags([]);
});
}
}, [setNewFiles]);


/*
* User selecet to edit a file, change to that file
*/
useEffect(() => {
// When user select a file to edit it
if (currentEditableFile && currentEditableFile !== theCurrentFile) {
setCurrentFile(currentEditableFile);
unstable_batchedUpdates(() => {
setDescription(currentEditableFile.description);
setTitle(currentEditableFile.title);
setTags(currentEditableFile.tags);
});
}
}, [currentEditableFile]);