monsterpiece
monsterpiece

Reputation: 779

props are undefined in child componentDidMount()

I'm having some trouble reading the values of my props in my child component's componentDidMount() hook

I can reference them in the child component itself but inside of the hook they show as undefined :(

hoping someone can point me in the right direction here...sorry for the weird component, using the arcgis api and npm esri-loader

APP.js

import React, { Component } from 'react'
import './App.css';
import {WebMapView} from './components/map.js'
import { RiEarthquakeLine } from 'react-icons/ri';
import { RiFloodLine } from 'react-icons/ri';
import { AiOutlineFire } from 'react-icons/ai';

export default class App extends Component {
  constructor(props){
    super(props)
    this.state={
      fire: "on",
      flood: "off",
      quakes: "off"
    }
    this.toggled = this.toggled.bind(this)
  }

  toggled(e){
    console.log("inside toggled",e.target.id)
  
  }

  render() {
    return (
      <div className="App">
      <header className="App-header"> </header>

  

    <div className="leftMenu">
          <div className="nav">
          <ul className="toggleopts">
            <li id="quake" onClick={this.toggled} className="toggleicon"><RiEarthquakeLine /></li>
            <li id="flood" onClick={this.toggled} className="toggleicon"><RiFloodLine/></li>
            <li id="fire"  onClick={this.toggled} className="toggleicon"><AiOutlineFire/></li>
          </ul>
          </div>  


            <div className="EsriMapContainer">
              <WebMapView props={this.state} />
            </div>
      </div>

     
      
    </div>
    )
  }
}


CHILD COMPONENT

import React from 'react';
import { loadModules } from 'esri-loader';

export class WebMapView extends React.Component {
  constructor(props) {
    super(props);
    this.mapRef = React.createRef();
  }

  componentDidMount() {

  var props = this.props

    // lazy load the required ArcGIS API for JavaScript modules and CSS
    loadModules(['esri/Map', 'esri/views/MapView',"esri/widgets/Search","esri/layers/FeatureLayer"], { css: true },props)
    .then(([ArcGISMap, MapView, Search, FeatureLayer],props) => {

      console.log(this.props) //undefined here

      const map = new ArcGISMap({
        basemap: 'dark-gray'
      });

      this.view = new MapView({
        container: this.mapRef.current,
        map: map,
        center: [-118, 34],
        zoom: 10
      });

   
      if(props.flood===false){
      var floodHazards = new FeatureLayer({
        url:
          "https://services9.arcgis.com/RHVPKKiFTONKtxq3/arcgis/rest/services/USA_Wildfires_v1/FeatureServer"
      });
      
      map.add(floodHazards);
    }


    if(props.fire==true){
      var fireAOE = new FeatureLayer({
        url:
          "https://earthobs1.arcgis.com/arcgis/rest/services/Live_Stream_Gauges/MapServer"
      });
      
      map.add(fireAOE);
    }

    if(props.quakes===false){
      var quakes = new FeatureLayer({
        url: "https://services1.arcgis.com/VAI453sU9tG9rSmh/arcgis/rest/services/Major_Earthquakes_features/FeatureServer"
      })
      
      map.add(quakes)
    }

var search = new Search({
        view: this.view
      });

      this.view.ui.add(search, "top-right");

    });
  }

  componentWillUnmount() {
    if (this.view) {
      // destroy the map view
      this.view.destroy();
    }
  }

  render() {
    return (
      <div className="webmap" ref={this.mapRef} />
    );
  }
}

Upvotes: 1

Views: 193

Answers (2)

krsna
krsna

Reputation: 4333

By Looking at your code, I found that you are using redundant props at a wrong place, that is inside your Promise code block.

All you need to do is, remove the redundant props in .then block.

  componentDidMount() {
    const props = this.props;
    loadModules(
      [
        "esri/Map",
        "esri/views/MapView",
        "esri/widgets/Search",
        "esri/layers/FeatureLayer"
      ],
      { css: true },
      props
    ).then(([ArcGISMap, MapView, Search, FeatureLayer]) => {
      console.log('props ', props)
    });
  }

I created a working example using Stackblitz.

Upvotes: 0

rahulxyz
rahulxyz

Reputation: 445

<WebMapView props={this.state} />

This part is not correct. If you want to pass fire from this.state, it is preferable to first deconstruct it. (or directly use this.state.fire)

const {first} = this.state

Then pass it as a props. You can change the name if you want.

<WebMapView fire={fire} />

In Child, this is wrong.

var props = this.props;

It is preferable to deconstruct it like

const {fire} = this.props

or directly use it this.props.fire

Upvotes: 1

Related Questions