我有一些副作用要应用到我的 React 组件中,并且想知道如何组织它们:
- 作为单次使用效果
- 或几个 useEffects
在性能和架构方面哪个更好?
我有一些副作用要应用到我的 React 组件中,并且想知道如何组织它们:
在性能和架构方面哪个更好?
您需要遵循的模式取决于您的用例。
第一:您可能会遇到需要在初始安装期间添加事件侦听器并在卸载时清理它们的情况,以及另一种需要清理特定侦听器并在 prop 更改时重新添加的情况。
在这种情况下,使用两个不同的方法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])
第二:当任何状态或props从定义的集合发生变化时,您需要触发 API 调用或其他一些副作用。在这种情况下,具有useEffect
要监控的相关依赖项的单个会更好
useEffect(() => {
// side effect here on change of any of props.x or stateY
}, [props.x, stateY])
第三:对于不同的更改集,您需要单独的副作用。在这种情况下,将相关的副作用分离到不同的useEffect
s
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]);