我有一个无状态功能组件(请参阅下面的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或Title中使用任何状态。
我怀疑这是因为React.memo/PureComponent只在state和amp;道具,可能在渲染之间有一个幻影道具或其他不等价的东西,但仍以某种方式传递到Title中??但我不知道为什么会这样,也不知道如何确认或解决这个问题。或者我只是错误地使用了React.memo?
我知道React的工作原理就是孩子们在父状态变化时重新渲染,但我需要一种方法来防止我的转换在不相关的状态变化后启动,而React.memo似乎没有起到作用。有什么想法吗?
在树上跟踪它让我找到了解决方案。事实证明,我在GameHeader前后使用的Material UI样式的组件包装器导致GameHeaderameHeader停止了重新安装。与Title相同,尽管在上面显示的示例中,我已经删除了该示例周围的样式组件包装器。
这些MUI风格的组件定义位于我的父功能组件中(因为它们使用useTheme(,所以我最终所做的是将这些MUI样式的组件定义移动到父功能组件之外(在导出默认语句之后(,无论出于何种原因,这都完全解决了问题。
感谢@Jayce444为我指明了正确的方向!