首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当我在父程序中使用一个自组织组件时,应重新设置我的备忘组件

当我在父程序中使用一个自组织组件时,应重新设置我的备忘组件
EN

Stack Overflow用户
提问于 2020-05-06 21:32:49
回答 2查看 1K关注 0票数 0

我有一个问题,一个图像闪烁,因为它是无缘无故地呈现,尽管使用React.memo,尽管它的道具或状态不被改变。

我成功地使用了这里,正确地利用了React.memo,BUUUT,因为一个我不明白的原因,如果我在父组件中使用一个高阶组件,那么备忘录就不再工作了,我又遇到了闪烁的问题。

这是一个说明问题的小吃。

以下是代码:

代码语言:javascript
运行
复制
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';

let interval = null

const Icon = ({ name }) => {
  // We emulate a rerender of the Icon by logging 'rerender' in the console
  console.log('rerender')
  return <Text>{name}</Text>
}

const Memo = React.memo(Icon, () => true)

const withHOC = (Comp) => (props) => {
  return <Comp {...props}/>
}

export default function App() {
  const [state, setState] = React.useState(0)
  const name = 'constant'
  // Change the state every second
  React.useEffect(() => {
    interval = setInterval(() => setState(s => s+1), 1000)
    return () => clearInterval(interval)
  }, [])
  // Remove this line and replace NewView by View to see the expected behaviour
  const NewView = withHOC(View)
  return (
    <NewView>
      <Memo name={name} />
    </NewView>
  );
}

我不明白为什么我的特写打破了回忆录,我不知道如何防止闪烁在我的应用程序,仍然能够使用特别.

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-05-06 22:04:52

您正在重新创建您的呈现函数中的临时属性。因此,在呈现之间,该组件的任何子组件都不能保持一致。

如果您将临时创建移出呈现之外,那么它将工作!

代码语言:javascript
运行
复制
const Text = 'span';
const View = 'div';

let interval = null

const Icon = ({ name }) => {
  // We emulate a rerender of the Icon by logging 'rerender' in the console
  console.log('rerender')
  return <Text>{name}</Text>
}

const Memo = React.memo(Icon, () => true)

const withHOC = (Comp) => (props) => {
  return <Comp {...props}/>
}

// move it out here!
// 
const NewView = withHOC(View)
// 

function App() {
  const [state, setState] = React.useState(0)
  const name = 'constant'
  // Change the state every second
  React.useEffect(() => {
    interval = setInterval(() => setState(s => s+1), 1000)
    return () => clearInterval(interval)
  }, [])
  // Remove this line and replace NewView by View to see the expected behaviour
  
  return (
    <NewView>
      <Memo name={name} />
    </NewView>
  );
}
ReactDOM.render(<App />, document.querySelector('#root'));
代码语言:javascript
运行
复制
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>

编辑:我在另一个回答中看到了你的评论。

好的,但是我如何在我的组件中使用临时的呢?因为我需要为专案小组提供道具和州政府.

如果您确实需要在组件中创建自组织,您可以使用useMemo包装它,因为如果useMemo的依赖项没有改变,React将保留在呈现之间的特殊引用(注意:如果钩子依赖项在每次呈现时发生变化,这将无法工作)。

代码语言:javascript
运行
复制
function App() {
  // ...
  const NewView = useMemo(() => withHOC(View), []);
}

虽然这是可行的,但它可能有点不稳定。一般来说,钩子和HOCs不是一起使用的模式。反应核心团队创建了钩子来取代HOCs。在你继续走这条路之前,我想看看你是否可以把你的专案写成一个钩子。我想你会发现这更自然。

票数 4
EN

Stack Overflow用户

发布于 2020-05-06 22:08:54

在每次重呈现时,您都会创建一个新的NewView,因此旧的(以及您的Icon)将被销毁。因此,它实际上并不是在Icon上发生的重呈现,而是一个 Icon的全新呈现。

如果您将const NewView = withHOC(View)移出您的App函数,您的HOC将被调用一次,创建一个将用于每次重呈现的NewView,这将防止您的Icon也被销毁,并且在您回忆录中,您可以安全地避免不必要的重呈现。

代码语言:javascript
运行
复制
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';

let interval = null

const Icon = ({ name }) => {
  // We emulate a rerender of the Icon by logging 'rerender' in the console
  console.log('rerender')
  return <Text>{name}</Text>
}

const Memo = React.memo(Icon, () => true)

const withHOC = (Comp) => (props) => {
  return <Comp {...props}/>
}

const NewView = withHOC(View);

export default function App() {
  const [state, setState] = React.useState(0)
  const name = 'constant'
  // Change the state every second
  React.useEffect(() => {
    interval = setInterval(() => setState(s => s+1), 1000)
    return () => clearInterval(interval)
  }, [])
  // Remove this line and replace NewView by View to see the expected behaviour
  return (
    <NewView>
      <Memo name={name} />
    </NewView>
  );
}

为了更好地理解正在发生的事情,我在您的这里组件上添加了一个日志NewView,这样您就可以看到该组件在每个父版本的重新呈现上都会卸载,而它必须通过创建一个全新的NewView和一个回忆录Icon来销毁。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61645789

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档