gpt4 book ai didi

Functional component state is not carried into the functions of the component(功能性组件状态不会被带入组件的功能中)

转载 作者:bug小助手 更新时间:2023-10-28 10:05:44 24 4
gpt4 key购买 nike



I have a functional component as below to draw some polygons on a Google Map. I removed operational details and left only bare minimum.

我有一个功能组件如下所示,在谷歌地图上绘制一些多边形。我删除了行动细节只留下了最少的细节。


In the console log of useEffect with polygons dependency, console shows the correctly updated polygons, which tells me that this is not any asynchronous issue. But in the initMap function it is showing the polygons array as empty array. As an alternative, if I provide the polygons array to initMap as a parameter, it is passed correctly

在控制台日志useEffect with Polygons Dependency中,Console显示正确更新的多边形,这告诉我这不是任何异步问题。但在initMap函数中,它将多边形数组显示为空数组。作为另一种选择,如果我将多边形数组作为参数提供给initMap,它将被正确传递


I though, state of a component must be accessible within its own methods, NO ? I have no clue how to fix this :/ Any ideas ?

但是,组件的状态必须在其自己的方法中可访问,不是吗?我不知道如何解决这个问题:/你有什么想法吗?


import { useContext, useState, useEffect } from "react";
import Helmet from "react-helmet";

function MyMap(props) {
const [polygons, setPolygons] = useState([]);

useEffect(() => {
console.log("Polygons updated useeffect : " + polygons);
if (window.initMap !== undefined) {
window.initMap();
}
}, [polygons]);

function initMap() {
const zoom = props.props.zoom;
const center = props.props.center;

const tmpMap = new window.google.maps.Map(
document.getElementById("google-map"),
{
center: center,
zoom: zoom,
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoomControl: false,
}
);

if (polygons !== undefined) {
polygons.forEach((polygon) => {
return new window.google.maps.Polygon({
paths: polygon,
strokeColor: "#FF0000",
map: tmpMap,
});
});
}

mapElement = (
<div
className="map-container"
id="google-map"
style={{ width: "100%", height: "100%" }}
>
{arrayObject}
</div>
);

return (
<section className="map-wrapper-container">
{mapElement}
<Helmet>
<script
type="text/javascript"
async={true}
defer={true}
src="https://maps.googleapis.com/maps/api/js?key=<APIKEY>&callback=initMap"
/>
</Helmet>
</section>
);
}
export default MyMap;

更多回答
优秀答案推荐

First of all, if you want to change the state of polygons, you should use setPolygons instead of just re-define the array, since it will not trigger re-render and React will act as polygons is not changed at all. I'd suggest this:

首先,如果要更改多边形的状态,应该使用setPolygons,而不只是重新定义数组,因为它不会触发重新渲染,而Reaction将充当根本不更改的多边形。我建议这样做:


  if (polygons !== undefined) {
setPolygons(prev => prev.map(((polygon) => {
return new window.google.maps.Polygon({
paths: polygon,
strokeColor: "#FF0000",
map: tmpMap,
});
})));
}

Second, in my opinion it's safer passing polygons to initMap(). But in case you don't want to, you will not need to pass polygons as dependency for the useEffect.

其次,在我看来,将多边形传递给initMap()更安全。但如果您不想这样做,则不需要将多边形作为useEffect的依赖项传递。


更多回答

Thanks for your comment @ngtrthinh , I could use the array as a parameter; yet my concern is about the concept here; why the polygons' state is not accessible in the initMap function. What could I possible be missing ?

感谢您的评论@ngtrthinh,我可以使用数组作为参数;但我关心的是这里的概念;为什么在initMap函数中无法访问多边形的状态。我可能会错过什么呢?

@GeoSystems It IS accessible, the thing that I think went wrong is how you change the state of polygons. First of all, polygons will be initialize as [], then React will render the component (which doesn't have the map yet). After the render, useEffect runs and "change" your polygons, but React won't re-render (as I mentioned above), so in your screen only the old polygons value is applied.

@地理系统它是可访问的,我认为错误的是你如何改变多边形的状态。首先,多边形将被初始化为[],然后Reaction将渲染组件(该组件还没有贴图)。渲染之后,useEffect运行并“更改”您的多边形,但Reaction不会重新渲染(如上所述),因此在您的屏幕中只应用旧的多边形值。

quoted from official useEffect docs: "If you specify the dependencies, your Effect runs after the initial render and after re-renders with changed dependencies." So the run order will be: init -> render -> useEffect (-> should be a render to show what changed in useEffect) Your useEffect doesn't "change" any state since you've only changed the value of polygons array, the address of the array (the one that React cares) is still the same. So React acts like nothing change, and your change will not be reflected.

引用官方的useEffect文档:“如果您指定了依赖项,您的效果将在初始渲染和更改了依赖项的重新渲染之后运行。”所以运行顺序是:init->Render->useEffect(->应该是一个Render来显示useEffect中更改了什么)你的useEffect不会“改变”任何状态因为你只改变了多边形数组的值,数组的地址(反应的那个)仍然是相同的。所以反应就像什么都没有改变一样,你的改变不会被反映出来。

OK, I dont see it that way. I had a hunch and tested this :

好吧,我不这么看。我有一种预感,然后测试了一下:

OK, after some further research, I found out that react changes the memory references to the state objects; i.e. the references to the same variable (polygons) are different in the MyMap component and initMap function. If I understand it correctly, I find this concept very confusing, particularly as JS abstracts the whole memory management and object references are not traceable.

好的,经过进一步的研究,我发现Reaction改变了对状态对象的内存引用;也就是说,在MyMap组件和initMap函数中对相同变量(多边形)的引用是不同的。如果我理解正确,我发现这个概念非常令人困惑,特别是因为JS抽象了整个内存管理,并且对象引用是不可跟踪的。

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com