简体   繁体   中英

Component state in ReactJS

First of all, I am new in ReactJS. I would like to display markers in my MapComponent. I made this work, but to be honest I think there should be better way to do it... I get props from my parent component, where they are loaded from JSON. I would like to pass coordinates from each item(from my JSON) into markers in state in my MapComponent. I used react-google-maps solution for google maps. Maybe someone could give me some advice what would be the best approach in this case? Thanks a lot for any tips!

export class MapComponent extends React.Component {

  constructor(props) {
    super(props)
    this.state = {
        markers: []
    }
  }


  getMarkers() {
    if (this.props.data.rows) {
      var markers = this.props.data.rows.map(function(item, i) {
        return {
          position: {
            lat: item.coordinate[0],
            lng: item.coordinate[1]
          },
          item: item
        }
      });
      this.setState({
        markers: markers
      });
    }
  }
  shouldComponentUpdate(nextProps, nextState) {
    return true;
  }
  componentDidUpdate() {
    this.getMarkers();
  }

  render() {
    return (
      <div className={styles.map}>
      <GoogleMapLoader
        containerElement={
          <div
            {...this.props}
            style={{
              height: "100%",
            }}
          />
        }
        googleMapElement={
          <GoogleMap
            ref={(map) => console.log(map)}
            defaultZoom={9}
            defaultCenter={{lat: 52.379189, lng: 4.899431}}>
            {this.state.markers.map((marker, index) => {
              return (
                <Marker
                {...marker}
                />
              );
            })}
          </GoogleMap>
        }
      />
      </div>
    );
  }
}

Since you are passing your state via props, you can ovoid creating a component class , you actually just need a simple representational component , it is supported since 0.14 (I guess). This representational components are just functions, representing the render function. This functions take props as param

So you Component will look more clean:

const MapComponent = (props) => {
  return (
    <div className={styles.map}>
      <GoogleMapLoader
        containerElement={
          <div
            {...props}
            style={{height: "100%"}}
          />
        }
        googleMapElement={
          <GoogleMap
            ref={(map) => console.log(map)}
            defaultZoom={9}
            defaultCenter={{lat: 52.379189, lng: 4.899431}}>
              {props.data.rows.map((item, index) => {
                const position = {
                  lat: item.coordinate[0],
                  lng: item.coordinate[1]
                };

                return (
                  <Marker
                    key={index}
                    position={position}
                    item={item}
                  />
              );
            })}
          </GoogleMap>
        }
      />
    </div>);
}

First, as @webdeb said , better to send the correct data using props. The use of state cause unnecessary redrawing of a component. Secondly, if for some reason you will need to handle the props and the state as you describe, componentDidUpdate method is not suitable for this purpose, you should replace it with componentWillReceiveProps

Something like:

import React, {Component} from 'react';
export class MapComponent extends Component {

    constructor(props) {
      super(props)
      this.state = {
          markers: []
     }
    }
    componentDidMount() {
        this.getMarkers(this.props);
    }
    componentWillReceiveProps(nextProps){
        if(this.props.data!==nextProps.data){
            const markers = this.getMarkers(nextProps);
            this.setState({
               markers: markers
            });
        }
    }

    getMarkers(props) {
        let markers = [];
        if (props.data.rows) {
            markers = props.data.rows.map(function(item, i) {
              return {
                 position: {
                   lat: item.coordinate[0],
                   lng: item.coordinate[1]
                 },
                 item: item
              }
           });

        } 
        return markers;
     }
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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