gpt4 book ai didi

reactjs - React.memo 不起作用 - 我错过了什么?

转载 作者:行者123 更新时间:2023-12-04 11:45:01 26 4
gpt4 key购买 nike

我正在重构我们的一些组件,所以我试图将 memoization 作为一些组件合并 5 月 使用相同的值重新渲染(例如,热链接图像 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 在之前的渲染中传递并且它是一样的,它知道不会再次重新渲染它但出于某种原因,它呢?

谢谢大家。非常感谢。

最佳答案

好吧,要么是 showAvatar并非总是如此或 CardHeader ListItem组件神奇地决定是否显示 child

示例

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>

关于reactjs - React.memo 不起作用 - 我错过了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62041890/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com