更新子prop会断开与父状态的连接

时间:2018-04-04 04:12:13

标签: reactjs

我使用react-google-maps在地图上显示标记。当我使用子组件中的SearchBox函数来设置props.locations我的地图Markers时。但是,当我使用父组件中的按钮来更新locationsMapWithASearchBox的状态时,子支柱不会识别该更改。如果我重新加载页面并只使用父组件上的按钮,则标记显示正确。我假设当我在子组件中设置prop时,我打破了child和parent之间的连接。

路径:Parent Component MapPage.jsx

export default class MapPage extends Component {
  constructor(props) {
    super(props);

    this.state = {
      companies: []
    }

    this.handleButtonASXMarketCap = this.handleButtonASXMarketCap.bind(this);
  }

  handleButtonASXMarketCap(limit, e) {
    e.preventDefault();

    Meteor.call('getASXTop100', limit, (error, result) => {
      if (result) {
        this.setStateOfCompanies(result);
      }
    });
  }

  setStateOfCompanies(data) {
    this.setState({
      companies: data
    })
  }

  render() {
    return (
      <div>
        <Button color="primary ml-2" onClick={(e) => this.handleButtonASXMarketCap(100, e)}>Top 100 ASX</Button>

        <MapWithASearchBox
          locations={this.state.companies}
        />
      </div>
    );
  }
}

路径:Child Component MapWithASearchBox.jsx

const MapWithASearchBox = compose(
  withProps({
    googleMapURL: "myUrl",
    loadingElement: <div style={{ height: `100%` }} />,
    containerElement: <div style={{ height: `400px` }} />,
    mapElement: <div style={{ height: `100%` }} />,
  }),
  lifecycle({
    componentWillMount() {
      const refs = {}

      this.setState({
        bounds: null,
        center: {
          lat: -23.696248, lng: 133.880731
        },
        zoom: 4,
        markers: [],

        onPlacesChanged: () => {
          const places = refs.searchBox.getPlaces();
          const bounds = new google.maps.LatLngBounds();

          places.forEach(place => {
            if (place.geometry.viewport) {
              bounds.union(place.geometry.viewport)
            } else {
              bounds.extend(place.geometry.location)
            }
          });
          const nextMarkers = places.map(place => ({
            position: place.geometry.location,
          }));
          const nextCenter = _.get(nextMarkers, '0.position', this.state.center);

          this.setState({
            center: nextCenter,
            markers: nextMarkers,
            zoom: 15
          });

          const lat = nextMarkers.map(x => x.position.lat());
          const lng = nextMarkers.map(x => x.position.lng());

          Meteor.call('runMethodTest', lat[0], lng[0], (error, result) => {
            if (result) {
              this.setState({
                locations: result
              });
            }
          });
        },
      })
    },
  }),
  withScriptjs,
  withGoogleMap
)(props =>
  <GoogleMap>
    <SearchBox
      ref={props.onSearchBoxMounted}
      bounds={props.bounds}
      controlPosition={google.maps.ControlPosition.TOP_LEFT}
      onPlacesChanged={props.onPlacesChanged}
    >
      <input
        type="text"
        placeholder="Customized your placeholder"
      />
    </SearchBox>

    {props.locations.map((location, index) => (
      <span key={location._id.location.lng}>
        <Marker
          position={location._id.location}
          onClick={() => props.onToggleOpen(index)}
        />
      </span>
    ))}
  </GoogleMap>
);

0 个答案:

没有答案