2

I have a higher order component that I try to modify a bit (I'm not familiar with recompose).

So thats my component:

<Map mycenter={mycenter}  />

I want the map-component to update or to rerendered if the mycenter is updated. I'm trying to modify the code from https://github.com/istarkov/google-map-thousands-markers/blob/master/src/Map.js

I made some modifications to the code. First, the map center is set to mycenter. That works.

withState('mapParams', 'setMapParams', ({ mycenter }) => ({ center:mycenter, zoom: 12 })),

After that the user can click somewhere and the center will be modified

withHandlers({
    onMapParamsChange: ({ setMapParams }) => ({ center, zoom, bounds }) => {
      setMapParams({ center, zoom, bounds });
      console.log('setMapParams', { center, zoom });
    },

Is there a way so that the component rerenders or the center is updated if "mycenter" is updated?

MichaelRazum
  • 789
  • 1
  • 10
  • 26
  • 2
    A classic state management problem. Look into using a library such as mobx or redux. Another solution would be to move the logic up the state tree to a parent so that when triggered it updates the children.. (am i making sense?) – rimraf Oct 23 '17 at 23:20
  • Like what @archae0pteryx said, instead of creating a local state, lifting the state to a parent or event a global store usually will solve this problem and produce more readable code. – wuct Oct 24 '17 at 02:34
  • @archae0pteryx Yes I’m using redux in my whole application. The mycenter state comes from redux. Im trying to pass the state over to the map component but don’t want to rewrite it. I guess that would solve that. Right now I’m working with classes and connect them to redux. Not sure how to do it with the HOC map Component. – MichaelRazum Oct 24 '17 at 05:45

2 Answers2

4

Currently, the best way is to use lifecycle. the callback of initial state (({ mycenter }) => ({ center:mycenter, zoom: 12 })) happens only once.

const enhanceMap = compose(
  withState('mapParams', 'setMapParams', ({ mycenter }) => ({ center: mycenter, zoom: 12 })),
  withStateHandlers({...}),
  lifecycle({
    componentWillUpdate(nextProps) {
      if (this.props.mycenter !== nextProps.mycenter)
        this.setState({mapParams: { center: nextProps.mycenter, zoom: 12 }})
    }
  })
)
Edan Chetrit
  • 4,713
  • 2
  • 20
  • 20
  • `componentWillUpdate` is no longer recommended:https://reactjs.org/docs/react-component.html#unsafe_componentwillupdate You should probably use `componentDidUpdate`. – Con Antonakos Jan 30 '19 at 21:12
2

Hope this don't come too late.

I find transforming props to state a little bit messy..

Right now, recompose allows you to send a function as a parameter for withProps method. You can do something like:

withProps( props => ({
  mycenter: props.mycenter,
  zoom: 12,
}))

This way, you will propagate your props down to your component, and it will update whenever the props change.