Ways to trigger a setState function by clicking on a Leaflet marker in a React TypeScript application

Currently, I have an array of equipment that is being displayed using Array.map. Additionally, I am utilizing a Context API that contains a state [selectedEquipmentId, setSelectedEquipmentId].

The objective is to trigger the setSelectedEquipmentId(equipmentId) function when clicking on the . While this seems straightforward with a simple onClick event, the existing approach does not seem to work with Leaflet and the solution remains elusive.

function Map() {
  const equipmentsPositions = useContext(EquipmentsPositionContext);
  const setSelectedEquipmentId = useContext(EquipmentIdContext);

  const center: LatLngExpression = [-19.151801, -46.007759];

  function getEquipmentById(equipmentId: string) {
    const filteredEquipment = equipmentsStateHistory.filter(
      (equipment) => equipment.equipmentId === equipmentId
    );

    return filteredEquipment[0];
  }

  return (
    <Box h="100vh" w="80%">
      <MapContainer
        center={center}
        zoom={10}
        scrollWheelZoom={true}
        style={{ height: "100%", width: "100%" }}
      >
        <TileLayer
          attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        />

        {equipmentsPositions?.map((equipmentPosition) => {
          const equipment = getEquipmentById(equipmentPosition.equipmentId);

          return (
            <Marker
              onClick={() => {setSelectedEquipmentId(equipment.equipmentId)}}
              key={equipment.equipmentId}
              position={[
                equipmentPosition.positions[equipmentsPositions.length - 1].lat,
                equipmentPosition.positions[equipmentsPositions.length - 1].lon,
              ]}
            >
              <Popup>
                <Text as="span" color={equipment.color}>
                  {equipment.name}
                </Text>
              </Popup>
            </Marker>
          );
        })}

      </MapContainer>
    </Box>
  );
}

export default Map;

In addition, here is the Context required for reference:

interface ISelectedEquipmentIdContext {
  selectedEquipmentId: string | ReactNode;
  setSelectedEquipmentId: React.Dispatch<React.SetStateAction<string>>
}

export const EquipmentIdContext = createContext<ISelectedEquipmentIdContext | null>(
  null
);

export function EquipmentIdProvider({ children }: IProps) {
  const [selectedEquipmentId, setSelectedEquipmentId] = useState<string>("");

  return (
    <EquipmentIdContext.Provider value={{ selectedEquipmentId: selectedEquipmentId, setSelectedEquipmentId: setSelectedEquipmentId }}>
      {children}
    </EquipmentIdContext.Provider>
  );
}

I have exhausted various attempts, but to no avail in resolving the issue.

Answer №1

It is recommended to avoid declaring state as:

const [selectedEquipmentId, setSelectedEquipmentId] = useState("");

Instead, consider defining the interface as:

selectedEquipmentId: string | ReactNode;

This might lead to issues as ReactNode cannot be a string. If ReactNode is unnecessary, it should be removed from the type. However, if it serves a purpose, it must be included in the state type.

Another option is using

ISelectedEquipmentIdContext['selectedEquipmentId']
, but for an Id, it is more suitable to stick with the string type.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Incorrect Configuration of Angular Testing Module Leads to Failure in Resolving Parameters (NgRx)

Struggling with setting up tests in my Angular CLI 6 project. Here's a snippet from my testing code: beforeEach(() => { spyOn(console, 'info'); TestBed.configureTestingModule({ providers: [ ConsoleLoggerEffects, prov ...

Classify Express v4 router as a class

Despite successful compilation and the server supposedly starting on the correct port, I encounter a "cannot access this route" error when attempting any of my registered routes. I've come up short in finding resources on using express with classes, ...

Getting the type from an ImmutableArray of MyType instances does not produce the desired results

In an attempt to enhance certain areas of a codebase, I came across multiple arrays utilized to convert information from our backend into user-friendly strings - similar to the structure below: export const MyMapping = [ { dbLabel: 'something', ...

Having issues with importing momentjs by reference in TypeScript with amd configuration

I'm puzzled by the difference in behavior between these two snippets: import * as moment from "../Typings/moment"; One works, while this one doesn't: /// <reference path="../Typings/moment.d.ts" /> import * as moment from "moment"; It t ...

Utilizing HttpClient in a static method service with Angular

One of my services contains a static method that I use for some initialization treatment. Within this method, I need to retrieve data from a web service @Injectable() export class FeaturesInitializationService { static allowedFeaturesModul ...

Mastering TypeScript in Router Configuration

I am currently working with a standard router setup. type Routes = '/' | '/achievements' | ... ; This helps in identifying the routers present in the project. However, I am faced with a new challenge of creating an array that includes ...

Changing the Row's Background Color in Angular When the Button is Clicked

My code includes a list where each row has a button to open a sidebar. Due to the large number of elements in the list, I want the background color of the row to turn yellow when the button is clicked, as a way to indicate what has been selected. Currently ...

Is it possible to directly parse a multipart/mixed response without needing to first convert it into a string?

My current challenge involves receiving a multipart/mixed response over HTTP that includes JSON data and PDFs in byte format. Due to Angular's limitations with handling such responses, I have resorted to converting the response into a string using the ...

I am looking for a way to convert the date format from "yyyy-MM-dd" to "dd-MM-yyyy" in NestJs

I need help with changing the date format from "yyyy-MM-dd" to "dd-MM-yyyy". Currently, my entity code looks like this: @IsOptional() @ApiProperty({ example: '1999-12-12', nullable: true }) @Column({ type: 'date', nullable: true } ...

Angular's Integration with PayPal for Shipping Costs

I am facing an issue with my e-commerce website where the receipt only displays the total payment of the items purchased. I have searched for an SDK that supports Angular or TypeScript PayPal integration, but could only find one for JavaScript which did ...

Exploring the depths of Typescript: Navigating through intricate mapping of keys and types in dynamic

Explaining this may be a bit tricky, but I'll start with stating my objective and then elaborate on the question as clearly as possible: Note: The version of typescript doesn't matter to me, any solution would be appreciated. interface Type {} ...

Is it possible to use a type assertion on the left hand side of an assignment in TypeScript?

While reading the TypeScript documentation, I came across type assertions but it seems they are limited to expressions only. I am looking to assert the type of a variable on the left side of an assignment statement. My specific scenario involves an Expres ...

Simulating NestJS Injected Connection Imported from Another Module

Today, I've been facing this persistent error: Encountering an issue with the ClubsService where Nest is unable to resolve dependencies (specifically DatabaseConnection). The error message prompts me to ensure that the argument DatabaseConnection at i ...

Creating a generic hashmap that can accept dynamic keys and an array of type T

In my attempt to create a robust typing interface for a hashmap in typescript, The hashmap consists of a key with a dynamic string name, and a values array containing a Generic type. I attempted to define the interface as follows: export interfa ...

Combining platform-express and platform-fastify for optimal performance

I am currently working on a NestJS application and my goal is to upload files using the package @types/multer. However, I encountered an issue while following the guidelines from the official documentation: https://i.sstatic.net/JCX1B.png Upon starting ...

In DynamoDB, when using Number in KeyConditionExpression, it is interpreted as a Map which can lead to unexpected

Setting In my TypeScript CDK project, I am dealing with the QueryInput-Object. The code snippet below shows how it's being used: const params: QueryInput = { TableName: criticalMessagesTableName, ProjectionExpression: 'message', ...

What is the reason for TypeScript allowing this promise chain without any compilation errors?

Although I am still relatively new to Typescript, I find myself grappling with a particular issue that has been perplexing me. I am unsure why the following code snippet triggers a compilation error: // An example without Promises (does not compile) funct ...

The control of the ThreeJS TransformControl has been relinquished

I am currently working on a project using Typescript within the Autodesk Forge Viewer environment. My goal is to restrict the movement of the ThreeJS transform control to a specific area defined by min and max values for X, Y, and Z coordinates. Additional ...

Using jest in typescript to simulate HttpRequest body and InvocationContext in @azure/functions

I have the following function and I am trying to write a test for it, but I'm having trouble figuring out how to mock HttpRequest import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions"; export async function ...

Troubleshooting Issue with Angular Library: Live Reload Feature Not Functioning

In setting up my Angular workspace, I have 3 libraries and one application (with more to be added in the future). This is how the TypeScript paths are configured: "paths": { "@lib/a/*": [ "projects/libs/a/*", ...