繁体   English   中英

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

[英]React.memo Not Preventing Re-renders of Stateless Functional Child Component that Takes In No Props

我有一个无状态功能组件(参见下面的标题),它使用 React-Reveal 在渲染时显示一些简单的标题元素。 除了没有内部 state 之外, Title也不会从其父组件( GameHeader )接收任何道具。 但由于某种原因,每当我从树中其他地方的另一个不相关组件更新整个应用程序 state 时,标题仍然会不断重新渲染,这会导致 React-Reveal 动画每次运行一些不相关的应用程序 state 更改。

// 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,但无济于事——它仍然会不断地重新渲染和重新触发其动画。 我正在使用钩子 + 上下文 API(带 useReducer 和调度)来更新我的应用程序 state 在应用程序的其他地方,但我没有直接在GameHeader中使用任何Z9ED39E2EA931586B6A985A6942EF573

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

我知道在父 state 更改上重新渲染的孩子正是 React 的工作原理,但我需要一种方法来防止我的转换在不相关的 state 更改后触发,并且 React.memo 似乎没有起到作用。 有什么想法吗?

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

这些 MUI 样式的组件定义位于我的父功能组件内(因为它们正在使用 useTheme),所以我最终做的是将这些 MUI 样式的组件定义移到父功能组件之外(在 export default 语句之后)并且,无论出于何种原因,完全解决了这个问题。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM