【发布时间】:2020-11-29 23:43:44
【问题描述】:
我有一个无状态功能组件(参见下面的Title),它使用 React-Reveal 在渲染时显示一些简单的标题元素。除了没有内部状态之外,Title 也不会从其父组件(GameHeader)接收任何道具。但是由于某种原因,每当我从树中其他地方的另一个不相关组件更新整体应用程序状态时,Title 仍然会不断重新渲染,这会导致 React-Reveal 动画每次运行一次不相关的应用状态更改。
// GameHeader.js
import React from 'react';
import Title from './Title';
import Options from './Options';
const GameHeader = () => {
return (
<div>
<Title />
<Options />
</div>
);
}
export default GameHeader;
// Title.js --> this component needs to stop re-rendering so much because it contains entrance animations
import React from 'react';
import { Typography } from '@material-ui/core';
import { useTheme } from '@material-ui/core/styles';
import Zoom from 'react-reveal/Zoom';
import Slide from 'react-reveal/Slide';
import Flip from 'react-reveal/Flip';
const Title = () => {
console.log("Title rendering");
const theme = useTheme();
return (
<>
<Typography variant="subtitle1" color="primary">
<Slide left>Sample</Slide>
</Typography>
<Typography variant="h1" style={{ color: `${theme.palette.indigo.main}` }}>
<Flip delay={800} duration={600} cascade>App</Flip>
</Typography>
<Typography variant="h2" style={{ color: `${theme.palette.orange.dark}` }}>
<Zoom delay={1100} cascade>Title</Zoom>
</Typography>
</>
);
}
export default React.memo(Title);
我尝试在 React.memo 中包装 Title 或将其转换为 PureComponent,但无济于事 - 它仍然会不断地重新渲染和重新触发其动画。我正在使用 hooks + Context API (w/useReducer & dispatch) 来更新应用程序中其他地方的应用程序状态,但我没有直接在 GameHeader 或 em> 标题。
我怀疑因为 React.memo/PureComponent 仅在 state 和 props 之间进行浅比较,所以可能存在 phantom prop 或渲染之间不等效的东西仍然传递到 Title强>不知何故??但我不知道为什么会这样,或者如何确认或解决这个问题。或者我只是错误地使用了 React.memo?
我知道子级在父状态更改时重新渲染正是 React 的工作原理,但我需要一种方法来防止我的转换在不相关的状态更改后触发,而 React.memo 似乎并没有起到作用。有什么想法吗?
【问题讨论】:
-
如果真的没有道具,那么
React.memo进行浅层比较的事实将是无关紧要的,因为它实际上没有比较任何东西。这里的一种选择是它正在重新安装,尽管我们不知道祖先组件或它们是如何工作的。如果动画只应该在 on mount 上播放,这也是有意义的 -
谢谢@Jayce444。它似乎正在重新安装,因为当我使用控制台日志语句和空的依赖项 [] 参数将 useEffect 添加到“标题”时,每次我的状态更改时都会收到控制台记录的语句。我真的不确定为什么会发生这种情况,但我现在正在梳理所有的父结构,看看我是否能解决这个问题。在那种情况下,我想 React.memo 也帮不了我。
-
是的,我也是这么想的。假设您没有通过使用诸如随机的
key道具手动触发重新安装,那么答案几乎肯定会是该组件树上某处的祖先之一正在重新安装。将不得不在树上找到它,然后调试它。应该解决这个问题
标签: javascript reactjs