在React中,如何防止地图上出现过多渲染



我在尝试基于子导航图中的useState设置className的方法时出错。

(代码剥离(:

const [activeLink, setActiveLink] = useState(0)
// removed code
{items.map((item, key) => {
const { title, link } = item
return (
<React.Fragment key={key}>
<Link
to={`/${link}`}
className={activeLink === 1 ? 'active' : ''}
>
{title}
</Link>
</React.Fragment>
)
})}

尝试1

{items.map((item, key) => {
const { title, link } = item
let testLink = null
testLink = pathname.toString().includes(link)
if (testLink === true && activeLink === 0) setActiveLink(1)
if (testLink === false && activeLink === 1) setActiveLink(0)
return (
<React.Fragment key={key}>
<Link
to={`/${link}`}
className={activeLink === 1 ? 'active' : ''}
>
{title}
</Link>
</React.Fragment>
)
})}

抛出错误:

重新渲染过多。React限制渲染次数以防止无限循环。

尝试2

const handleactive = link => (pathname.toString().includes(link) ? 1 : 0)
useEffect(() => {
if (activeLink === false && handleactive() === 1) return setActiveLink(1)
return setActiveLink(0)
}, [activeLink])

尝试3

const handleactive = link => {
if (activeLink === 0 && pathname.toString().includes(link) === true) return setActiveLink(1)
return setActiveLink(0)
}

{items.map((item, key) => {
return (
<React.Fragment key={key}>
<Link
to={`/${link}`}
className={activeLink === 1 ? 'active' : ''}
handleactive={handleactive(link)}
>
{title}
</Link>
</React.Fragment>
)
})}

研究

  • 未捕获的不变冲突:重新渲染过多。React限制渲染次数以防止无限循环
  • 重新渲染过多。React限制渲染次数,以防止出现无限循环。下一个js错误
  • "错误:重新渲染过多。React限制渲染次数,以防止出现无限循环">
  • React限制渲染次数以防止无限循环。。。重新渲染过多
  • 错误:重新渲染过多。React限制渲染次数,以防止出现无限循环。React js
  • 如何避免错误:重新渲染过多。React限制渲染次数以防止无限循环

我做错了什么?如何在地图中更新状态?

在渲染过程中不能调用useStatesetState函数。

贴图在每个渲染上运行,因此每个渲染都有可能(取决于条件(调用setActiveLink

如果您希望更新地图中每个项目的状态,您可能需要为链接创建一个额外的组件。

然后,链接可以保持自己的状态,也可以通过从父级传递给它们的回调函数设置父级状态。

// Map in existing parent component
{items.map((item, key) => {
return (
<NavLink 
key={key} 
{...item} 
pathname={pathname} 
/>
)
})}
// New component
const NavLink = ({title, link, pathname}) => {
const active = useMemo(() => {
return pathname.toString().includes(link)
}, [pathname, link]);
return (
<Link
to={`/${link}`}
className={active ? 'active' : ''}
>
{title}
</Link>
);
}

您不必执行并返回state方法。

删除返回并仅执行,这可以解决问题

发生的事情是,您在地图内部调用setActiveLink,从而触发渲染。渲染之后,调用映射中的代码,再次调用setActiveLink,导致另一次重新渲染,最终导致无限循环。

您需要将setActiveLink放入只调用一次的onClick中。

示例3:

<Link
to={`/${link}`}
className={activeLink === 1 ? 'active' : ''}
onClick={() => handleactive(link)}
>

最新更新