当我将函数表达式传递给useEffect依赖数组时,为什么会创建无限循环?函数表达式不会更改组件状态,它仅引用它。
// component has one prop called => sections
const markup = (count) => {
const stringCountCorrection = count + 1;
return (
// Some markup that references the sections prop
);
};
// Creates infinite loop
useEffect(() => {
if (sections.length) {
const sectionsWithMarkup = sections.map((section, index)=> markup(index));
setSectionBlocks(blocks => [...blocks, ...sectionsWithMarkup]);
} else {
setSectionBlocks(blocks => []);
}
}, [sections, markup]);
如果标记更改了状态,我可以理解为什么它会创建一个无限循环,但它不仅仅引用prop节。
对于那些寻求解决此问题的人
const markup = useCallback((count) => {
const stringCountCorrection = count + 1;
return (
// some markup referencing the sections prop
);
// useCallback dependency array
}, [sections]);
所以我不是在寻找与此问题相关的代码。如果可能的话,我正在寻找有关发生这种情况的详细说明。
我对为什么然后仅仅寻找答案或解决问题的正确方法感兴趣。
当在useEffect外部声明的useEffect依赖关系数组中传递函数时,为什么状态和prop均未更改,为什么会导致重新渲染。
答案 0 :(得分:4)
问题在于,每个渲染周期都会重新定义markup
。 React使用浅对象比较来确定值是否更新。每个渲染周期markup
都有不同的参考。但是,您可以使用useCallback
来记住该功能,以便引用稳定。您是否为短绒棉启用了react hook rules?如果这样做了,它可能会标记出来,告诉您原因,并提出解决参考问题的建议。
const markup = useCallback(
(count) => {
const stringCountCorrection = count + 1;
return (
// Some markup that references the sections prop
);
},
[count, /* and any other dependencies the react linter suggests */]
);
// No infinite looping, markup reference is stable/memoized
useEffect(() => {
if (sections.length) {
const sectionsWithMarkup = sections.map((section, index)=> markup(index));
setSectionBlocks(blocks => [...blocks, ...sectionsWithMarkup]);
} else {
setSectionBlocks(blocks => []);
}
}, [sections, markup]);
答案 1 :(得分:0)
为什么在传递函数表达式时会创建无限循环
“无限循环”是指组件反复渲染,因为markup
函数是每次组件渲染时useEffect
是一个新的函数引用(内存中的指针),并且useCallback
触发重新渲染。渲染,因为它是依赖项。
该解决方案就像@ drew-reese所指出的那样,使用markup
钩子来定义您的library(vegan)
#> Le chargement a nécessité le package : permute
#> Le chargement a nécessité le package : lattice
#> This is vegan 2.5-6
library(ggplot2)
set.seed(2)
community_matrix <- matrix(
sample(1:100,300,replace=T),nrow=10,
dimnames=list(paste("community",1:10,sep=""),paste("sp",1:30,sep="")))
example_NMDS <- metaMDS(community_matrix, # Our community-by-species matrix
k=2, trace = 0) # The number of reduced dimensions
data.scores <- as.data.frame(scores(example_NMDS))
data.scores$site <- rownames(data.scores)
data.scores$grp <- rep(c("1", "2"), each = 5)
species.scores <- as.data.frame(scores(example_NMDS, "species"))
species.scores$species <- rownames(species.scores)
ggplot() +
geom_text(data=species.scores,aes(x=NMDS1,y=NMDS2,label=species), alpha=1) + # add the species labels
geom_point(data=data.scores,aes(x=NMDS1,y=NMDS2,shape=as.factor(grp), colour=as.factor(site))) + # add the point markers
geom_text(data=data.scores,aes(x=NMDS1,y=NMDS2,label=site, colour=as.factor(site)), vjust=0) + # add the site labels
#scale_colour_manual(values=c("1" = "red", "2" = "blue")) +
coord_equal() +
theme_bw()
函数。