React 在渲染最终值之前遍历状态变量所具有的每个值

React looping over every value that a state variable has had before rendering on the final value

我有一个 class 监听地图上的点击,当检测到点击时,它被添加到数组 routeWayPoints:

import React, { useState } from "react";
import Tab from "./Tab";

import RouteWayPointsTable from "./RouteWayPointsTable";

import { map, removeFromTheMap, addToTheMap } from "../javascript/mapInterprater";

function RouteAnalysisTab() {
  const [routeWayPoints, setRouteWayPoints] = useState([]);

  function beginPlottingRoute() {
    setRouteWayPoints([]);
  }


  map.on("click", onMapClick);

  function onMapClick(event) {
    if (isRouteActive) {
      setRouteWayPoints(routeWayPoints.concat(event.latlng));
    }
  }

  return (
    <Tab id="analyse-route" title="Analyse route" className="data-display__tab-content">
      <h3>Analyse route</h3>
      {!isRouteActive && routeWayPoints.length > 0 && (
        <button className="button" id="new-route-button" type="button" onClick={() => beginPlottingRoute()}>
          Plot new route
        </button>
      )}
      <div className="data-display__tab-content--route-analysis">
        {!isRouteActive && routeWayPoints.length === 0 && (
          <button className="data-display__button--home" id="plot-route-button" type="button" onClick={() => beginPlottingRoute()}>
            Plot a route
          </button>
        )}
        <RouteWayPointsTable routeWayPoints={routeWayPoints} />
      </div>
    </Tab>
  );
}

export default RouteAnalysisTab;

我将数组传递给 RouteWayPointTable 组件并尝试遍历每个项目并使用 RouteWayPointRow 组件在 table 中创建一行。

import React from "react";

import RouteWayPointRow from "../components/RouteWayPointRow";

function RouteWayPointsTable(props) {
  return (
    <div id="route-analysis">
      <table className="data-display__waypoint-table" id="analyse-route-waypoints">
        <thead>
          <tr>
            <th className="data-display__waypoint-table--way-point-col">Way point</th>
            <th className="data-display__waypoint-table--lat-col">Latitude</th>
            <th className="data-display__waypoint-table--lng-col">Longitude</th>
            <th className="data-display__waypoint-table--remove-col"></th>
          </tr>
        </thead>
        <tbody>
          {props.routeWayPoints.map((wayPoint, index) => {
            return <RouteWayPointRow wayPoint={wayPoint} index={index} key={index} />;
          })}
        </tbody>
      </table>
    </div>
  );
}

export default RouteWayPointsTable;

现在正在显示行,但我观察到一些我没有预料到的奇怪行为。

当我向数组添加点时,React 在呈现最新点之前遍历数组存在的每个状态,因此更新 table 所需的时间呈指数增长,因为每次添加新点时,它都必须对数组执行更多循环。

所以我的问题是我在组件内声明了地图监听器,所以每次我点击地图时都会创建一个新的监听器,这会导致 React 重新渲染 DOM

function RouteAnalysisTab() {
  const [routeWayPoints, setRouteWayPoints] = useState([]);

  function beginPlottingRoute() {
    setRouteWayPoints([]);
  }


  map.on("click", onMapClick);

可能不是最优雅的解决方案,但在创建侦听器之前删除侦听器可以解决问题:

  map.off("click");
  map.on("click", onMapClick);