Это немного странно, и я не уверен, почему это происходит точно.
Когда компонент монтируется, я вызываю функцию, которая в моем приложении делает HTTP-запрос для получения массива объектов. Затем я обновляю 3 состояния в методе карты.
enquiries
- это просто ответ от HTTP-запроса activeProperty
- который определяет, какой идентификатор объекта является текущим активным 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
изображения, которые мигают / перерисовывают. Я думал, что алгоритм diff включился бы здесь и не перерисовал бы изображения, поскольку они - те же самые изображения?
Но кажется, что styled-components
добавляет новый класс каждый раз, когда вы нажимаете на ChannelListItem
, так что он перерисовывает изображение. Но ТОЛЬКО когда открыто окно инструментов разработки?
Почему это так? Есть ли способ обойти это?
Я могу использовать встроенные стили вместо styled-components
, и он работает, как и ожидалось, хотя я хотел посмотреть, есть ли способ обойти это без удаления styled-components
У меня есть CODESANDBOX , чтобы проверить себя