[英]How to stop react re-rendering component, if part of the state changes?
如果只有部分状态发生变化,有没有办法停止反应重新渲染?
问题是,每次我将鼠标悬停在标记上时,都会打开或关闭一个弹出窗口,这会导致所有标记重新呈现,即使mystate
没有改变,只有activePlace
状态在改变。 console.log(myState);
每次我悬停在标记内外时都在运行。
我尝试使用 useMemo 钩子,但不知道如何使用它。 有什么帮助吗?
这是我的代码:
import React, { useEffect, useState } from 'react';
import { Map, TileLayer, Marker, Popup } from 'react-leaflet';
import axios from 'axios';
import { v4 as uuidv4 } from 'uuid';
import { Icon } from 'leaflet';
const myicon = new Icon({
iconUrl: './icon.svg',
iconSize: [20, 20]
});
const MyMap = () => {
const [myState, setMyState] = useState(null);
const [activePlace, setActivePlace] = useState(null);
const getData = async () => {
let response = await axios
.get('https://corona.lmao.ninja/v2/jhucsse')
.catch(err => console.log(err));
let data = response.data;
setMyState(data);
// console.log(data);
};
useEffect(() => {
getData();
}, []);
if (myState) {
console.log(myState);
return (
<Map
style={{ height: '100vh', width: '100vw' }}
center={[14.561, 17.102]}
zoom={1}
>
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>'
url={
'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png'
}
/>
{myState.map(country => {
return (
<Marker
key={uuidv4()}
position={[
country.coordinates.latitude,
country.coordinates.longitude
]}
onmouseover={() => {
setActivePlace(country);
}}
onmouseout={() => {
setActivePlace(null);
}}
icon={myicon}
/>
);
})}
{activePlace && (
<Popup
position={[
activePlace.coordinates.latitude,
activePlace.coordinates.longitude
]}
>
<div>
<h4>Country: {activePlace.country}</h4>
</div>
</Popup>
)}
</Map>
);
} else {
return <div>Loading</div>;
}
};
export default MyMap;
这一行是你的问题:
key={uuidv4()}
为什么要在每次渲染时创建唯一 ID? ID 的意义在于它在渲染之间保持不变,以便 React 知道它不必在 DOM 中重新绘制该组件。
每当状态发生变化时,都会发生两个阶段,渲染阶段和提交阶段。
渲染阶段首先发生,这是所有组件执行其渲染函数的地方(在函数组件的情况下是整个组件)。 返回的 JSX 变成 DOM 节点并添加到虚拟 DOM 中。 这是非常有效的,与重新渲染实际 DOM 不同。
在提交阶段,将新的虚拟 DOM 与真实 DOM 进行比较,在真实 DOM 中发现的任何差异都将被重新渲染。
React 的重点是限制真实 DOM 的重新渲染。 不限制虚拟DOM的重新计算。
这意味着当activePlace
更改时,整个组件运行其渲染周期activePlace
。
然而,因为你在每个渲染周期都给每个country
一个全新的 ID,虚拟 DOM 认为每个国家都发生了变化(它使用 ID 来比较以前的 DOM 值),所以实际 DOM 中的所有国家也得到重新-rendered,这可能就是您看到滞后问题的原因。
ID 应该是与国家相关的东西,例如国家代码,而不仅仅是随机的 UUID。 如果您确实使用随机 UUID,请将它们与国家/地区一起保存,以便始终使用相同的 UUID。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.