我正在重构我们的一些组件,因此我尝试合并记忆,因为一些组件可能会使用相同的值重新呈现(例如,热链接图像URL,除非它们相同)。
我有一个简单的组件:
const CardHeader = props => {
// img is a stringand showAvatar is a boolean but it's always true
const { ..., showAvatar, img } = props;
return (
<CardHeader>
<ListItem>
// AvatarImage shouldn't re-render if img is the same as previous
{showAvatar && <AvatarImage img={img} />
</ListItem>
</CardHeader>
);
}
然后是阿凡达笠美:
const AvatarImage = React.memo(props => {
console.log("why is this still re-rendering when the img value hasn't changed?");
const { img } = props;
return (
<ListItemAvatar>
{img ?
<Avatar src={img} />
:
<Avatar>
Some initials
</Avatar>
}
</ListItemAvatar>
);
});
我还试着传递备忘录的第二个论点:
(prevProps, nextProps) => {
return true; // Don't re-render!
}
但是console.log仍然每次都显示出来。我显然遗漏了什么,或者不太明白这是怎么回事。这个组件是几个级别下来,但它通过在img如果它是每次可用的,所以我希望它知道,如果img是通过在以前的渲染,它是一样的,它知道不重新渲染它,但出于某种原因真的吗?
谢谢大家。非常感谢。
您是否启用了StrictMode
?这将导致用记忆的组件发生反应。备注
以渲染两次。
更多信息:
好吧,要么show Avatar
并不总是true,要么CardHeader
ListItem
组件神奇地决定是否显示儿童
示例
const { useState, useEffect, memo, createContext, useContext } = React;
const getAvatars = () => Promise.resolve([
{
src: 'https://i.picsum.photos/id/614/50/50.jpg'
},
{
src: 'https://i.picsum.photos/id/613/50/50.jpg'
}
])
const Avatar = ({src}) => {
console.log('avatar render');
return <img src={src} alt="avatar"/>
}
const MemoAvatarToggle = memo(({src}) => {
console.log('memo avatar with \'expression &&\' render');
return <div>
{src ? <img src={src} alt="avatar"/> : <div>Test </div>}
</div>
})
const CardHeader = ({children}) => {
const luck = Boolean(Math.floor(Math.random() * 1.7));
return <div>
{luck && children}
</div>
}
const ListItem = ({children}) => {
return <div>
{children}
</div>
}
const ShowAvatarContext = createContext()
const App = (props) => {
const [avatars, setAvatars] = useState([]);
const [toggle, setToggle] = useState(false);
const [showAvatar, setShowAvatar] = useContext(ShowAvatarContext);
useEffect(() => {
let isUnmounted = false;
let handle = null;
setTimeout(() => {
if(isUnmounted) {
return;
}
setShowAvatar(true);
}, 500);
getAvatars()
.then(avatars => {
if(isUnmounted) {
return;
}
setAvatars(avatars)
})
const toggle = () => {
setToggle(prev => !prev);
handle = setTimeout(toggle, 1000);
//setShowAvatar(prev => !prev);
}
handle = setTimeout(toggle, 1000);
return () => {
isUnmounted = true;
clearTimeout(handle);
}
}, []);
return <div>
<CardHeader>
<ListItem>
{showAvatar && avatars.map((avatar, index) => <MemoAvatarToggle key={index} src={avatar.src}/>)}
</ListItem>
</CardHeader>
{toggle ? 1 : 0}
</div>
}
const ShowAvatarProvider = ({children}) => {
const state = useState(false);
return <ShowAvatarContext.Provider value={state}>
{children}
</ShowAvatarContext.Provider>
}
ReactDOM.render(
<ShowAvatarProvider>
<App/>
</ShowAvatarProvider>,
document.getElementById('root')
);
<script src="https://unpkg.com/react/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<div id="root"></div>
此代码显示#datepicker输入组件,但单击后,它不会打开。它也不能调用简单的$(“#日期选择器”)。日期选择器();方法请提供一些解决方案。 简单的datepicker()方法带有自己的默认设置,但我在这个方法中进行了自己的自定义。 在div标签中,它是在body标签中定义的,但我已经使它简短。span标签用于嵌入带有日期选择器输入组件的图标。在这种情况下,我使用的是字形压光。但是在那之前,
问题内容: 我刚开始使用Python,却不知道什么是记忆以及如何使用它。另外,我可以举一个简化的例子吗? 问题答案: 记忆有效地指基于方法输入记忆方法调用的结果(“记忆”→“备忘录”→要记忆),然后返回记忆的结果,而不是再次计算结果。你可以将其视为方法结果的缓存。有关更多详细信息,请参见第387页的Cormen等人的《算法简介》(3e)中的定义。 一个简单的示例,使用Python中的记忆来计算阶乘
问题内容: 我试图将onscroll事件处理程序添加到特定的dom元素。看下面的代码: 代码非常简单,如您所见,我想处理div#list滚动。当我运行此示例时,它不起作用。所以我尝试直接在render方法上绑定this._handleScroll,它也不起作用。 因此,我打开了chrome inspector,直接使用以下命令添加了onscroll事件: 它正在工作!我不知道为什么会这样。这是Re
问题内容: 为什么colspan属性在React中不起作用?我创建了呈现以下内容的简单组件: 编辑:解决 这是解决方案。React期望属性名称为 colSpan ,而不是colspan。在浪费了荒谬的时间去发现这个小小的邪恶事实之后,想出了这一点。 问题答案: 来自React的DOM差异文档: 所有DOM属性和属性(包括事件处理程序)都应包含驼峰,以与标准JavaScript样式保持一致。 如果您
好的,我想我最好在这里补充一点,我知道代码看起来不太好,但我认为它会起作用,所以我很高兴你能解释为什么它不仅有效,而且无效。我也很高兴听到你对这个问题的解决办法! 我很难理解为什么下面的代码块似乎没有按照预期工作,我的意思是记忆
如何使用备忘录模式 在 ViewController.swift 里加上下面两个方法: //MARK: Memento Pattern func saveCurrentState() { // When the user leaves the app and then comes back again, he wants it to be in the exact same state