React and setState

I am evaluating GoJS as a component of a planned system. I have run into a problem using GoJS with React.

I have created a basic project based on some of the available samples with functionality to add new nodes and edit the text in nodes which works fine. However when I add an eventlistener and set a state inside it, any changes (changed texts and added nodes) revert back to original. Positions are strangely kept but all other user induced changes disappear.

I can read the state with no problems but as soon as I write anything to the state I get this behaviour. There seems to be no problem setting states outside of the eventlisteners. I have tried some different approaches as binding this to the eventlistener as well as using arrow functions with a variable with this in. I have also tried both building my component as a class component and as a functional component with the same result. I have also tried to use the stateful example for React modified to work with JS (as it is TypeScript).

Is this a known problem? Am I doing something wrong or is it a bug?

What state are you changing in the event listener, and how are you doing it?

I am changing the react state for the component. I have both used the setState function for a class component and state hooks for a functional component. It doesn’t seem to matter what actionlistener though. Adding and changing nodes works fine as long as I do not set any states in the action listeners and etting the state does work however it does affect any changes I have made in the diagram.

We need more specifics. Are you referring to GoJS diagram listeners where you’re trying to set state? What does your setState call look like?

handleModelChange(changes) {
    this.setState({something: "something"});
}

render() {
    return (
        <ReactDiagram
            initDiagram={this.initDiagram.bind(this)}
            divClassName='diagram-component'
            nodeDataArray={[
                { key: 0, name: 'Alpha', loc: '0 0' },
                { key: 1, name: 'Beta', loc: '150 0' },
                { key: 2, name: 'Gamma', loc: '0 150' },
                { key: 3, name: 'Delta',  loc: '150 150' }
            ]}
            linkDataArray={[
                { key: 1, from: 0, to: 1 },
                { key: 2, from: 0, to: 2 },
                { key: 3, from: 2, to: 3 },
                { key: 4, from: 1, to: 3 }
            ]}
            onModelChange={this.handleModelChange.bind(this)}
        />
    );
}

I assume you’ve seen gojs-react-basic along with the intro page on React.

The handleModelChange listener is only called when a model change takes place within GoJS. It is up to you to keep your state in sync with the GoJS model changes that occur, which gojs-react-basic demonstrates.

Under what circumstances are you trying to call setState? I can’t tell from your code above what it is you’re actually trying to do. If you could put up a CodeSandbox, it would be easier to help you.

Here is the code in CodeSandbox:

I have removed as much of what is unnecessary for this particular problem. If you change the text in a node and then deselect it will revert back to the original text. You can move the nodes and they will keep their positions though. In my project I also have added the possibility to add new nodes and as mentioned before they also revert back to the original state of the diagram. However I didn’t think it was necessary to include that into this example as you can notice the same effect with the text.

If you then comment out line 77, where the react state is set, you will see that everythjing works fine apart from the fact that I now are not able to have my states set from an event.

As an interesting detail, I also set up some code in CodeSandbox for a functional component with the same problem and there I can’t even move the nodes. Not sure what is the difference.

I think you may have missed some things in your CodeSandbox, it won’t run.

But based on the code in ProcessView.js, you still don’t seem to be synchronizing GoJS model changes with your state. In fact, you are sending the initial node and link data arrays to the ReactDiagram component with every state update. I suggest you spend some time going over and understanding the links I sent earlier go the basic sample and the intro.

Strange, it seems to run fine for me.

Anyway I think I might understand what is wrong. I was under the impression that the nodeDataArray was only the initial values and that it after that would ignore the props and internally kept the data structure updated. Apparently I was wrong.

Thank you for the help