0

when i am trying to state this.setState({ ["node_" + n]: test_node }) i am getting error this.setState is not a function , here i have uploaded my full code, can anyone please check my code and help me to resolve this issue ?

import createEngine, { DiagramModel, DefaultNodeModel, DefaultLinkModel } from '@projectstorm/react-diagrams';
import * as React from 'react';
import { CanvasWidget } from '@projectstorm/react-canvas-core';
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';

const data_json = require('../client-demo-simple/data.json');

const all_tables = data_json.base.tables;

console.log(all_tables)

export default () => {
    this.state = {
        node_level: []
    }
    //1) setup the diagram engine
    var engine = createEngine();
    //2) setup the diagram model
    var model = new DiagramModel();

    //3-A) create a default node
    let test_node = null;
    for (let n = 0; n < all_tables.length; n++) {
        let table_name = all_tables[n].name;
        let table_description = all_tables[n].description;
        let table_fields = all_tables[n].fields;
        let random_number_1 = Math.floor(Math.random() * 101);
        let random_number_2 = Math.floor(Math.random() * 101);
        let random_number_3 = Math.floor(Math.random() * 101);
        test_node = new DefaultNodeModel({
            name: table_name,
            color: 'rgb(' + random_number_1 + ',' + random_number_2 + ',' + random_number_3 + ')'
        });
        this.setState({ ["node_" + n]: test_node })
        test_node.setPosition(100, 100);
        for (let n = 0; n < table_fields.length; n++) {
            let field_name = table_fields[n].name;
            test_node.addOutPort(field_name);
        }

        model.addAll(test_node);

    }
    engine.setModel(model);
    model.setLocked(true);
    return (
        <DemoCanvasWidget>
            <CanvasWidget engine={engine} />
        </DemoCanvasWidget>
    );
};
Nikul Panchal
  • 1,542
  • 3
  • 35
  • 58

3 Answers3

1

setState is inherented from React.Component. you aren't creating a class that extents Component, you are creating a functional component. To use state in a functional component you need to use hooks.

Brian Thompson
  • 13,263
  • 4
  • 23
  • 43
0

you are using this.setState. this refer to the scope of any class. So in order to use this.<anything> it has to be a class component. You can still create and update state in functional component using useState hook supported in react 16 and above.

0

As others mentioned, since it's a functional component you need to use useState instead of this.setState. It's a little awkward since you are adding nodes dynamically depending on their ID, but you can do it this way:

import createEngine, {
  DiagramModel,
  DefaultNodeModel,
  DefaultLinkModel
} from '@projectstorm/react-diagrams';
import * as React from 'react';
import { CanvasWidget } from '@projectstorm/react-canvas-core';
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';

const data_json = require('../client-demo-simple/data.json');

const all_tables = data_json.base.tables;

console.log(all_tables);

export default () => {
  const [state, setState] = React.useState({ node_level: [] }); // <-- best to hold all state like this, since you're adding nodes to state dynamically

  const addNodeToState = (nodeId, newNode) => setState({ ...state, [`node_${nodeId}`]: newNode }); // <-- new function to make adding nodes easier. Must spread existing state first

  //1) setup the diagram engine
  var engine = createEngine();
  //2) setup the diagram model
  var model = new DiagramModel();

  //3-A) create a default node
  let test_node = null;
  for (let n = 0; n < all_tables.length; n++) {
    let table_name = all_tables[n].name;
    let table_description = all_tables[n].description;
    let table_fields = all_tables[n].fields;
    let random_number_1 = Math.floor(Math.random() * 101);
    let random_number_2 = Math.floor(Math.random() * 101);
    let random_number_3 = Math.floor(Math.random() * 101);
    test_node = new DefaultNodeModel({
      name: table_name,
      color: 'rgb(' + random_number_1 + ',' + random_number_2 + ',' + random_number_3 + ')'
    });

    addNodeToState(n, test_node); // <-- use the function we just created to add node to state

    test_node.setPosition(100, 100);
    for (let n = 0; n < table_fields.length; n++) {
      let field_name = table_fields[n].name;
      test_node.addOutPort(field_name);
    }

    model.addAll(test_node);
  }
  engine.setModel(model);
  model.setLocked(true);
  return (
    <DemoCanvasWidget>
      <CanvasWidget engine={engine} />
    </DemoCanvasWidget>
  );
};

Be careful using setState here, since it will overwrite the entire state. If you want to edit other parts of the state you would probably want to make other functions to ensure you're always spreading the existing state first, i.e. const updateSomething = (key, value) => setState({...state, [key]: value })

Flagship1442
  • 1,688
  • 2
  • 6
  • 13