Javascript React.memo不阻止重新呈现不接受任何道具的无状态功能子组件

Javascript React.memo不阻止重新呈现不接受任何道具的无状态功能子组件,javascript,reactjs,Javascript,Reactjs,我有一个无状态的功能组件(请参见下面的标题),它使用React-Reveal在render上显示一些简单的标题元素。除了没有内部状态,Title也不会从父组件(GameHeader)接收任何道具。但出于某种原因,每当我从树中其他位置的另一个不相关组件更新整个应用程序状态时,标题仍然会不断重新呈现,这导致每次一些不相关的应用程序状态更改时,React Reveal动画都会运行 // GameHeader.js import React from 'react'; import Title fr

我有一个无状态的功能组件(请参见下面的标题),它使用React-Reveal在render上显示一些简单的标题元素。除了没有内部状态,Title也不会从父组件(GameHeader)接收任何道具。但出于某种原因,每当我从树中其他位置的另一个不相关组件更新整个应用程序状态时,标题仍然会不断重新呈现,这导致每次一些不相关的应用程序状态更改时,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);
//GameHeader.js
从“React”导入React;
从“./Title”导入标题;
从“./Options”导入选项;
const GameHeader=()=>{
返回(
);
}
导出默认游戏头;
//Title.js-->此组件需要停止如此多的重新渲染,因为它包含入口动画
从“React”导入React;
从“@material ui/core”导入{排版};
从“@material ui/core/styles”导入{useTheme};
从“反应显示/缩放”导入缩放;
从“反应显示/幻灯片”导入幻灯片;
从“反应显示/翻转”导入翻转;
常量标题=()=>{
控制台日志(“标题呈现”);
const theme=useTheme();
返回(
样品
应用程序
标题
);
}
导出默认反应备忘录(标题);
我尝试过在React.memo中包装Title,或者将其转换为PureComponent,但没有效果——它仍然会不必要地重新渲染和重新触发其动画。我正在使用hooks+上下文API(w/useReducer&dispatch)来更新应用程序中其他地方的应用程序状态,但我没有直接在游戏头标题中使用任何该状态

我怀疑,因为React.memo/PureComponent只是在状态和道具之间做了一个肤浅的比较,所以可能有一个幻影道具或一些在渲染之间不等价的东西仍然以某种方式传递到标题中??但我不知道为什么会这样,也不知道如何确认或解决。或者我只是错误地使用了React.memo


我知道孩子们在父状态更改时重新渲染是React的工作方式,但我需要一种方法来防止在不相关的状态更改和React后触发我的转换。memo似乎没有起到作用。有什么想法吗?

从树上追溯,我找到了解决方案。事实证明,我在GameHeader周围使用的材料UI样式的组件包装每次都导致GameHeader重新安装,当我移除样式化组件包装时,GameHeader停止重新安装。与Title相同,尽管在我上面展示的示例中,我已经从该组件包装器中删除了样式化组件包装器

这些MUI样式的组件定义位于父功能组件内部(因为它们使用的是useTheme),因此我最终将这些MUI样式的组件定义移动到父功能组件之外(在导出默认语句之后),无论出于何种原因,彻底解决了这个问题


感谢@Jayce444为我指明了正确的方向

如果真的没有道具,那么
React.memo
进行肤浅比较的事实就无关紧要了,因为它实际上没有比较任何东西。这里的一个选择是重新安装,尽管不知道祖先组件或它们如何工作,我们不能说。如果动画只能在MountThank@Jayce444上播放,那么这也是有意义的。它似乎正在重新装载,因为当我使用控制台日志语句和空的dependency[]参数向“Title”添加useffect时,每次状态更改时,我都会得到控制台日志语句。我真的不知道为什么会发生这种情况,但我现在正在梳理所有的父结构,看看我是否能弄清楚这一点。在这种情况下,我想我的反应。备忘录也帮不了我。是的,我也这么想。假设您没有使用随机
道具之类的东西手动触发重新装载,那么答案几乎肯定是该组件树上某个地方的祖先之一正在重新装载。你必须找到它,然后调试它。应该解决这个问题吗?我正在努力解决一个类似的问题,即即使没有道具更改,组件仍然使用react memo重新渲染,您提到您跟踪了树,您是如何做到这一点的?谢谢