1

I've tried make project with listing of cafes and markers in Google MAP their locations.

Idea is to click on place to select cafe and - get selcted appropriate markers and vice versa (click marker - get focused appropriate cafe in listing)

I have hierarhy of nested components like:

< App>:
   <List>
     <place1>
     <place2>
     ....
     <place10>
   </List>
   <Map>
    <marker of place1/>
    <marker of place2/>
   ...
   <marker of place10/>
  </Map>
</App>

I can make simple way just keep information which cafe selected in variable inside State of top parent - App.

But I dont want to fire rendering all this whole tree of components - its a lot work for browser.

I can keep focused value inside state of each child components placeX and markerX. So When I click some placeX is toggle to focused:true and send to next previous component to focused:false through function in parent- List. So - its just 2 child components going to re-render.

But how to fire changes in child components - in next branch: ?

K D
  • 15
  • 5

1 Answers1

1

But I dont want to fire rendering all this whole tree of components - its a lot work for browser.

You just need to pass proper properties to each component and use extends React.PureComponent to ensure it doesn't re-render component if nothing has been changed in props.

Imagine you have focused property in your App State which equals to X, which is actually focused. So you shouldn't pass it roughly to all components (as they will re-render each focus change), but you should calculate proper property, i.e. isFocused = state.focused === X.

Then it will re-render two components - the one which is focused next and the one which was focused before.

EDIT:

class App

...
updateFocus(x) {
  this.updateState('focused', x)
}

render() {
  const focused = this.state.focused;
  <Map focused={focused} updateFocus={updateFocus} ... />
}

class Map

...
render() {
  const {focused, updateFocus} = this.props;

  return <div>
    {this.renderMarkerItem(x, focused, updateFocus)}
  </div>
}

renderMarkerItem(x, focused, updateFocus) {
  const isFocused = focused === x;
  return <Marker x={x} focused={focused} updateFocus={updateFocus}>
}
...

React.PureComponent vs React.Component

extempl
  • 2,638
  • 22
  • 34
  • @KD Please consider marking the response as `Accepted` (Checkmark on the left) if it fixes your issue. – extempl Feb 26 '19 at 18:28
  • Unfortunatelly its doesnt work. I used **extends React.PureComponent** in all class components instead of **extend React.Component**. I made TopParent class property **isFocused** and function **window.updateFocus(x){this.isFocused=x}** that call in deep nested child component onClick event. So ... TopParent property **isFocused** get value from grand children, but its doesnt fire re-render appropriate childrens. – K D Feb 27 '19 at 04:25
  • Sorry! I just got research - I have to fire forceUpdate() – K D Feb 27 '19 at 04:32
  • @KD `forceUpdate()` although it is noted in the link I added this is not necessary (`shallowCompare` should work in your case perfectly). I bet the issue is in a different place. How are you passing the `isFocused` property to nested components? – extempl Feb 27 '19 at 05:36
  • @KD Please check the sketch I added in the answer. – extempl Feb 27 '19 at 05:48