projectstorm / react-diagrams

a super simple, no-nonsense diagramming library written in react that just works
https://projectstorm.cloud/react-diagrams
MIT License
8.6k stars 1.17k forks source link

TypeError: Cannot read property 'offsetWidth' of null. When switching between multiple engines using ant tabs. #748

Open agarwalishan opened 3 years ago

agarwalishan commented 3 years ago

Hey, I have made a component in which I am initializing engine directly or with the serialized diagram if passed as props. This component has key, serialized-diagram as props. Whenever key changes the component is destroyed as per react rules and component is re-mounted that means engine gets reinitialized. And at that time I am getting this error. Actually key is changing whenever I am switching Ant Tabs to display respective engine. And this error does not come always generally when tabs are switched quickly. When I was working with only one component like this then problem never appeared. Can someone please tell me what could be the reason?

Please ZoomIn images if not clearly visible image image

And if someone knows what could be the reason for this error if not related to my case then also please comment so that I can move in right direction.

agarwalishan commented 3 years ago

@dylanvorster Please tell

chestnut3108 commented 3 years ago

I am facing the same issue please help!

dylanvorster commented 3 years ago

You would need to provide a reproducible case for us. Also I unfortunately cannot provide integration support.

bknill commented 3 years ago

I'm having exact same problem.

The diagram loads fine the first time, if I remove the component, then re-add it I get this error.

the issue may be to do with a re-render, but as it doesn't affect normal usage, could you catch the error and ignore it in the code?

image

image

This seems to be new, we've had this diagram for a while and haven't seen it before.

axelmarciano commented 3 years ago

I've managed to fix it with this trick:


const setupEngine = () => {
    const engine = createEngine()
    const model = new DiagramModel()
    const node1 = new DefaultNodeModel({
      name: 'Node 1',
      color: 'rgb(0,192,255)',
    })
    node1.setPosition(100, 100)
    model.addAll(node1)
    engine.setModel(model)
    return engine
}

const engine = setupEngine()

return (
  <div className={classes.container}>
    {!!engine && <CanvasWidget engine={engine} />}
  </div>
)

However, I don't really know why this problem occurred.

agarwalishan commented 3 years ago

@axelmarciano your proposed solution didn't worked for me.

bknill commented 3 years ago

@agarwalishan the problem is caused by a re-render. I had the same issue, I had to delay rendering until all the data was ready.

The above solution didn't work but setting a flag to only render the diagram once did work,

bknill commented 3 years ago

@agarwalishan I fixed it with a really simple

    componentWillMount() {
        this.setState({loading: true})
        this.timeout = setTimeout(() => {
            if(this.state.loading)
                this.setState({loading: false})
        },1)
        this.loadDiagram()
    }

    componentWillUnmount(){
        clearTimeout(this.timeout)
    }

And only render if loading === false

agarwalishan commented 3 years ago

@bknill Thanks for telling but I am already using this approach. This approach works fine but it is not perfect fix for this bug.