繁体   English   中英

React 组件中的删除按钮无法从页面获取 useState

[英]A delete button in React component cannot get the useState from page

我正在制作一个 Google Map API 应用程序。 但是我在从组件调用 setMarker(useState) 时遇到了麻烦。

它说,未捕获的类型错误:无法读取未定义的属性(读取“过滤器”)。

我想制作一个表格来显示我的搜索位置结果并存储到 useState(markers)。 但是,当我想通过单击按钮删除位置结果时,它不起作用。 我应该怎么做才能制作删除按钮。 谢谢

我的 Map.js/App.js

import React, { useState, useEffect, useRef } from "react";
import {
  GoogleMap,
  useJsApiLoader,
  Marker,
  StandaloneSearchBox,
} from "@react-google-maps/api";

import Tablerecord from "../components/Tablerecord";

const libraries = ["places"];

const containerStyle = {
  width: "100%",
  height: "400px",
};

const inputStyle = {
  width: "100%",
  height: "500px",
};

const center = {
  lat: 22.7658314,
  lng: -22.4137297,
};

const options = {
  disableDefaultUI: true,
  zoomControl: true,
};

function App() {
  const [markers, setMarkers] = useState([]);
  const searchBox = useRef(null);

  const [searchPlaceCenter, setSearchPlaceCenter] = useState([
    parseFloat(43.7658314),
    parseFloat(-79.4137297),
  ]);

  const { isLoaded } = useJsApiLoader({
    id: "google-map-script",
    googleMapsApiKey: "API-KEY",
    libraries,
  });

  return isLoaded ? (
    <div>
      <StandaloneSearchBox
        onLoad={(ref) => (searchBox.current = ref)}
        onPlacesChanged={async (event) => {
          await // Find the search field value and make it be center value.
          setSearchPlaceCenter([
            parseFloat(
              searchBox.current.getPlaces()[0].geometry.location.lat()
            ),
            parseFloat(
              searchBox.current.getPlaces()[0].geometry.location.lng()
            ),
          ]);
          //  Store Search geolocation value to useState markers for Red markers
          setMarkers((current) => [
            ...current,
            {
              lat: searchBox.current.getPlaces()[0].geometry.location.lat(),
              lng: searchBox.current.getPlaces()[0].geometry.location.lng(),
              name: searchBox.current.getPlaces()[0].formatted_address,
              time: new Date(),
            },
          ]);
        }}
      >
        <input
          type="text"
          name="address"
          placeholder="Search Address"
          autoComplete="off"
          style={{
            boxSizing: `border-box`,
          }}
        ></input>
      </StandaloneSearchBox>

      <GoogleMap
        mapContainerStyle={containerStyle}
        zoom={8}
        //  Set center to searchPlace location to change center
        center={{
          lat: parseFloat(searchPlaceCenter[0]),
          lng: parseFloat(searchPlaceCenter[1]),
        }}
        options={options}
      >
        {markers.map((marker) => (
          <Marker
            key={marker.time.toISOString()}
            position={{
              lat: parseFloat(marker.lat),
              lng: parseFloat(marker.lng),
            }}
          />
        ))}
      </GoogleMap>

      {/* !!!!!!!!Here is my question !!!!!!*/}
      {markers.map((marker) => (
        <div>
          <Tablerecord key={marker.time} marker={marker} />
        </div>
      ))}
    </div>
  ) : (
    <div>Loading...</div>
  );
}

export default React.memo(App);

我的 Tablerecord.js(组件)

import React, { useState } from "react";
import styles from "../styles/tablerecord.module.css";

const Tablerecord = (marker,{markers,setMarkers}) => {


  const handleRemoveLocation = (e) => {
    const name = e.target.getAttribute("name");
    console.log(markers) // undefined
    setMarkers(markers.filter((item) => item.name !== name));
  };

  return (
    <div className={styles.table}>
      <center>
          {/* This work, can show name,lat and lng */}
        <p name={marker.marker.name}>Name: {marker.marker.name}</p>
        <p>
          lat: {marker.marker.lat}, lng: {marker.marker.lng}, Added Time:{" "}
          {marker.marker.time.toTimeString()}
        </p>

        {/* Delete button I want to ask */}
        <button name={marker.name} onClick={handleRemoveLocation}>
          x
        </button>
      </center>
    </div>
  );
};

export default Tablerecord;

您已经接近了,但还没有完全通过正确的道具发送到表格记录组件。

<Tablerecord key={marker.time} marker={marker} markers={markers} setMarkers={setMarkers} />

然后,

const Tablerecord = (props) => {
   const { marker, markers, setMarkers } = props; 
   // ...
}

或者,如果您愿意:

const Tablerecord = ({ marker, markers, setMarkers }) => {
   // ...
}

我相信您需要将状态添加到组件中

<Tablerecord key={marker.time} marker={marker} markers={markers} setMarkers={setMarkers} />

感谢以上所有评论!

最后,我调整了“Tablerecord”组件的代码和“Map.js”的一些代码。

这是我的代码

Tablerecord.js(组件)

import React, { useState } from "react";
import styles from "../styles/tablerecord.module.css";

const Tablerecord = ({ marker, markers, setMarkers }) => {
  const handleRemoveLocation = (e) => {
    const name = e.target.getAttribute("name");
    //   markers will output an Object to use .filter
    // filter out the item which is equal to the name.
    setMarkers(markers.filter((item) => item.name !== name));
  };

  return (
    <div className={styles.table}>
      <center>
        {/* String type - name , lat, lng and time */}
        <p>Name: {marker.name}</p>
        <p>
          lat: {marker.lat}, lng: {marker.lng}, Added Time:{" "}
          {marker.time.toTimeString()}
        </p>
        {/* marker.name can let setMarkers detect the name */}
        <button name={marker.name} onClick={handleRemoveLocation}>
          x
        </button>
      </center>
    </div>
  );
};

export default Tablerecord;

地图.js

<Tablerecord key={marker.time} marker={marker} markers={markers} setMarkers={setMarkers} />

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM