Skip to content

Have any suggestions for where to put something like an Esri or Leaflet Map object in Flux architecture? #1279

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Robert-W opened this issue Jan 25, 2016 · 9 comments

Comments

@Robert-W
Copy link

Do you have any suggestions for how to handle a mutable map object that manages it's own state and controls it's own rendering (to canvas or appending images as map layers) in a flux architecture? I know you require your stores to be essentially immutable which is why I am not sure where to put this.

Typically where I work we build our UI in React and use Flux to model our UI state (currently using Alt but I want to switch to Redux). We are however primarily an Esri shop so almost all of our applications use Esri's JSAPI and we frequently have to interact with the map object to add/remove/show/hide layers/graphics, apply definitions, do queries, etc.

We have come up with two approaches but was curious what you guys think or if you know of a better approach.

One method is to put the map object in the store, and then make changes to it using esri's api and route all of our functionality through actions, so we can emit change events anytime we interact with it and then derive our UI state from this map object. However we are just storing a reference to the map in the store and mutating it every time(we can't not mutate it because of how their api works) and this can get complex because not all UI can be derived directly from the map easily. It often requires parsing strings from arrays or deeply nested json objects which can be error prone.

The other method we have used is to store the map in the global scope under an app variable and take it out of flux completely. We then store a minimal amount of information about the map in the stores, just enough so we can render the UI (so things like which layers are visible and the state of their controls). We then interact with the map object after the store changes using the functions that are subscribed to the store. This way the store is immutable but we are duplicating a little bit of data.

@sompylasar
Copy link

  1. You should not put non-plain objects to the Redux state store -- it should be serializable.
  2. You can put essential map state, like marker placement, layer on-off state etc. into the Redux state store.
  3. You should wrap your map JSAPI component into a React component to do rendering the React-way, having props declaring the desired UI state, and having the component to determine the set of map JSAPI calls to change the map UI from its current state to the desired state obtained from props
  4. You should connect the component to Redux state store to map the state to its props.

@Robert-W
Copy link
Author

Hmm interesting.

So if I have an App component. I should map my essential map state to props and pass it to the Map component. Then in the Map I would translate the received props to API calls or pass those further down to the map controls so they could render correctly?

Then would the reference to the map live in the map component? The JSAPI map is a Dojo dijit unfortunately so typically we render a div in our Map component and then after the component mounts, we call something like app.map = new Map('map', mapOptions); but we want to get away from putting it in a global variable.

@Robert-W
Copy link
Author

Sorry if this is the wrong place for this, seems like more of a general Flux question, but since we are considering switching from Alt.js to Redux I figured I would ask here to see if redux had any helpers for this kind of thing (like the mapStateToProps).

@gaearon
Copy link
Contributor

gaearon commented Jan 26, 2016

I’ll close this as a duplicate of #606.

@gaearon gaearon closed this as completed Jan 26, 2016
@Robert-W
Copy link
Author

thanks @gaearon

@markerikson
Copy link
Contributor

@Robert-W : you may want to take a look at https://github.com/lelandrichardson/react-native-maps and https://github.com/uber/react-map-gl. Those both appear to be good implementations of React components wrapping JS map libraries.

@Robert-W
Copy link
Author

thanks @markerikson

I will check out their implementation. Looks promising, most examples I have seen just load a map and call it the quits, so it's nice to see one a little less trivial.

@sompylasar
Copy link

Then would the reference to the map live in the map component? The JSAPI map is a Dojo dijit unfortunately so typically we render a div in our Map component and then after the component mounts, we call something like app.map = new Map('map', mapOptions); but we want to get away from putting it in a global variable.

Yes. I don't know Dojo specifics, but generally you would store a reference to your map JSAPI object right on the React Map component, and you would initialize the map JSAPI object with a React div's "ref" to the browser DOM element, not with a string identifier.

@Robert-W
Copy link
Author

Sounds good to me, I will try that out. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants