为了账号安全,请及时绑定邮箱和手机立即绑定

如果部分状态发生变化,如何停止反应重新渲染组件?

如果部分状态发生变化,如何停止反应重新渲染组件?

Qyouu 2022-06-05 10:37:52
如果只有部分状态发生变化,有没有办法停止重新渲染?问题是每次我将鼠标悬停在标记上时,都会打开或关闭一个弹出窗口,它会导致所有标记重新渲染,即使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='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <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}              />            );          })}
查看完整描述

1 回答

?
皈依舞

TA贡献1851条经验 获得超3个赞

这条线是你的问题:

key={uuidv4()}

为什么要在每个渲染上创建一个唯一 ID?ID 的意义在于它在渲染之间保持不变,以便 React 知道它不必在 DOM 中重新绘制该组件。

每当状态发生变化时,都会发生两个阶段,即渲染阶段提交阶段

渲染阶段首先发生,这是所有组件执行其渲染功能的地方(在功能组件的情况下是整个组件)。返回的 JSX 被转换为 DOM 节点并添加到虚拟 DOM中。这非常有效,并且与重新渲染实际 DOM 不同。

在提交阶段,将新的虚拟 DOM 与真实 DOM 进行比较,在真实 DOM 中发现的任何差异都将重新渲染。

React 的重点是限制真实 DOM 的重新渲染。不是限制虚拟DOM的重新计算。

这意味着整个组件在更改时运行其渲染周期是完全可以的activePlace

country然而,因为你在每个渲染周期给每个国家都赋予了一个全新的 ID ,虚拟 DOM 认为每个国家都发生了变化(它使用 ID 来比较以前的 DOM 值),所以实际 DOM 中的所有国家也会重新获得渲染,这可能就是您看到延迟问题的原因。

ID 应该是与国家相关的东西,例如国家代码,而不仅仅是一个随机的 UUID。如果您确实使用随机 UUID,请将它们与国家/地区一起保存,以便始终使用相同的 UUID。


查看完整回答
反对 回复 2022-06-05
  • 1 回答
  • 0 关注
  • 80 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信