reactjs - 当 Chrome 开发工具打开时,样式化组件内的图像重新渲染
问题描述
这有点奇怪,不知道为什么会这样。
当组件挂载时,我调用一个函数,在我的应用程序中发出 HTTP 请求以获取对象数组。然后我在 map 方法中更新 3 个状态。
enquiries
- 这只是来自 HTTP 请求的响应
activeProperty
- 它定义了当前活动的对象 ID
channelDetails
- 解析一些响应数据以用作传递给子组件的道具。
const [enquiries, setEnquiries] = useState({ loading: true });
const [activeProperty, setActiveProperty] = useState();
const [channelDetails, setChannelDetails] = useState([]);
const getChannels = async () => {
// In my actual project,this is an http request and I filter responses
const response = await Enquiries;
const channelDetailsCopy = [...channelDetails];
setEnquiries(
response.map((e, i) => {
const { property } = e;
if (property) {
const { id } = property;
let tempActiveProperty;
if (i === 0 && !activeProperty) {
tempActiveProperty = id;
setActiveProperty(tempActiveProperty);
}
}
channelDetailsCopy.push(getChannelDetails(e));
return e;
})
);
setChannelDetails(channelDetailsCopy);
};
useEffect(() => {
getChannels();
}, []);
然后我返回一个子组件ChannelList
,它使用样式化组件向元素添加样式并呈现子元素。
const ChannelList = ({ children, listHeight }) => {
const ChannelListDiv = styled.div`
height: ${listHeight};
overflow-y: scroll;
overflow-x: hidden;
`;
return <ChannelListDiv className={"ChannelList"}>{children}</ChannelListDiv>;
};
在ChannelList
组件内部,我映射enquiries
状态并渲染ChannelListItem
在数组中对象的索引上具有分配键的组件,并接受channelDetails
状态和onClick
处理程序。
return (
<>
{enquiries &&
enquiries.length > 0 &&
!enquiries.loading &&
channelDetails.length > 0 ? (
<ChannelList listHeight={"380px"}>
{enquiries.map((enquiry, i) => {
return (
<ChannelListItem
key={i}
details={channelDetails[i]}
activeProperty={activeProperty}
setActiveProperty={id => setActiveProperty(id)}
/>
);
})}
</ChannelList>
) : (
"loading..."
)}
</>
);
在组件中,我根据状态ChannelListItem
从道具渲染两个图像details
channelDetails
const ChannelListItem = ({ details, setActiveProperty, activeProperty }) => {
const handleClick = () => {
setActiveProperty(details.propId);
};
return (
<div onClick={() => handleClick()} className={`ChannelListItem`}>
<div className={"ChannelListItemAvatarHeads"}>
<div
className={
"ChannelListItemAvatarHeads-prop ChannelListItemAvatarHead"
}
style={{
backgroundSize: "cover",
backgroundImage: `url(${details.propertyImage})`
}}
/>
<div
className={
"ChannelListItemAvatarHeads-agent ChannelListItemAvatarHead"
}
style={{
backgroundSize: "cover",
backgroundImage: `url(${details.receiverLogo})`
}}
/>
</div>
{activeProperty === details.propId ? <div>active</div> : null}
</div>
);
};
现在,只要打开 chrome 开发工具窗口并单击不同ChannelListItems
的图像闪烁/重新渲染,就会出现问题。我原以为差异算法会在这里启动并且不会重新渲染图像,因为它们是相同的图像?
但似乎styled-components
每次单击 a 时都会添加一个新类ChannelListItem
,因此它会重新渲染图像。但仅当开发工具窗口打开时?
为什么是这样?有没有解决的办法?
我可以使用内联样式而不是styled-components
它,它按预期工作,但我想看看是否有办法解决这个问题而不删除styled-components
我有一个CODESANDBOX可以自己检查
解决方案
推荐阅读
- python-3.x - 是否可以在 __name__ == '__main__' 块中获取要执行的脚本的内容(其文件名或内容)?
- python - 为什么建议不要在 conda 基础环境中安装额外的包?它的目的是什么?
- ruby - Jekyll:不允许操作@ apply2files
- python - Python,getopt,如何获取列表
- angular - 使用 i18n 角度翻译列表项
- ruby-on-rails - 如何验证关联的每个实例的限制,而不是 Rails 中的关联本身
- c# - 在 foreach 控制循环中缺少一些 Button.attributes
- apache-poi - 使用 apache-poi 使用来自放心 json 响应的值更新 excel
- javascript - 在 Typescript 的同一类中从另一个方法调用方法
- php - HTTP服务器可以将结构化文件目录中的多个文件发送到浏览器吗