0

Here my stackblitz:

https://stackblitz.com/edit/svgtest

JSX

import React, { Component } from 'react';
import { render } from 'react-dom';
import './style.css';
import { observer } from 'mobx-react';
import { observable } from 'mobx';
import { MountingViewModel } from './MountingViewModel';
import { Roof } from './roof';
import { Facade } from './facade';

interface AppProps { }
interface AppState {
  name: string;
}

@observer
class App extends Component<AppProps, AppState> {
  constructor(props) {
    super(props);
    this.state = {
      name: 'React'
    };
  }

  onClick = (e) => {
    alert(e.currentTarget.id);
    // set opcacity to 0.5 to all others id`s
  }

  @observable mountings: Set<MountingViewModel> = new Set();

  roofViewModel: MountingViewModel = new MountingViewModel(false, "roof");
  facadeViewModel: MountingViewModel = new MountingViewModel(false, "facade");

  componentDidMount() {
    this.mountings.add(this.roofViewModel);
    this.mountings.add(this.facadeViewModel);
  }

  renderSvg() {
    return <svg height="400" width="400" xmlns="http://www.w3.org/2000/svg">
      {  
        this.mountings.has(this.roofViewModel) && <Roof id={"roof"} />
      }
      {
        this.mountings.has(this.facadeViewModel) && <Facade id={"facade"} />
      }

    </svg>
  }

  onMouseOver = (e) => {
    let data = e.currentTarget;
    alert(data.style);
  }

  render() {
    return this.renderSvg()

  }
}

render(<App />, document.getElementById('root'));

The roof and facade component are not rendered because the Set.has method does not return true although I would say the object equality is given!

Why are those 2 components not rendered?

Pascal
  • 12,265
  • 25
  • 103
  • 195
  • What in the world is a "stackblitz"? – Pointy Jul 09 '18 at 21:58
  • @Pointy a runnable example on the website named "stackblitz". You could have clicked on the link, also. – jonrsharpe Jul 09 '18 at 21:59
  • @jonrsharpe well relevant code should always be posted **here**. That's the whole point. – Pointy Jul 09 '18 at 22:02
  • @Pointy then say *"you should put a [mcve] in the question itself"*. – jonrsharpe Jul 09 '18 at 22:04
  • Also OP no two objects are ever equal. Even if they contain all the same properties with all the same values, they will not compare as equal for the purposes of `Set.prototype.has()`. – Pointy Jul 09 '18 at 22:04
  • @jonrsharpe I did vote to close :) – Pointy Jul 09 '18 at 22:04
  • @Pointy The relevant code IS posted. Its minimal, complete and verifiable via click on the link. Just try it, don`t be shy... Objects are equal when they are the same instances. And I reuse those instances. – Pascal Jul 09 '18 at 22:09
  • @Pascal I think the problem is that [MobX doesn't have observable Sets](https://github.com/mobxjs/mobx/issues/69). It works with [a map or a regular array](https://stackblitz.com/edit/svgtest-xgc1h3). – Tholle Jul 09 '18 at 22:36
  • @Pascal well if those properties never change, what's the point of even checking? If they *do* change, how does that happen? – Pointy Jul 09 '18 at 23:28
  • 1
    @Tholle You were right, convert Set to array and it worked! – Pascal Jul 10 '18 at 20:21

1 Answers1

0

MobX doesn't support observable Sets yet. Instead you could keep your views in an observable array and your component will re-render as it should when the array changes.

@observer
class App extends Component<AppProps, AppState> {
  // ...

  @observable mountings: MountingViewModel[] = [];

  componentDidMount() {
    this.mountings.push(this.roofViewModel);
    this.mountings.push(this.facadeViewModel);
  }

  renderSvg() {
    return <svg height="400"   width="400" xmlns="http://www.w3.org/2000/svg">
      {  
        this.mountings.indexOf(this.roofViewModel) === -1 && <Roof id={"roof"} isSelected={this.roofViewModel.isSelected}  />
      }
      {
        this.mountings.indexOf(this.facadeViewModel) === -1 && <Facade id={"facade"} isSelected={this.facadeViewModel.isSelected} />
      }
    </svg>
  }

  render() {
    return this.renderSvg()
  }
}
Tholle
  • 108,070
  • 19
  • 198
  • 189