0

So I am almost certainly doing something wrong, and not understanding the underlying library here, but how do I make it so that I can update a row item externally to React-Data-Grid?

example below, after 5s the first col of the first row is updated, but the data in the table is not. Why? and How to change?

let cols = [
  {
    key: 'sapAssetNumber',
    name: 'SAP Asset number',
    editable: false
  },
  {
    key: 'assetDescription',
    name: 'Description',
    editable: false
  },
  {
    key: 'assetNBV',
    name: 'Asset NBV',
    editable: false
  },
  {
    key: 'salePrice',
    name: 'Sale price',
    editable: false
  }
];

let rows = [
    {
        "id" : "0",
        "sapAssetNumber" : "woof",
        "isAlreadyDisposed" : "",
        "assetDescription" : "test",
        "assetNBV" : "100",
        "salePrice" : "100"
    },
    {
        "id" : "0",
        "sapAssetNumber" : "",
        "isAlreadyDisposed" : "",
        "assetDescription" : "test",
        "assetNBV" : "100",
        "salePrice" : "100"
    },
    {
        "id" : "this",
        "sapAssetNumber" : "is",
        "isAlreadyDisposed" : "a",
        "assetDescription" : "test",
        "assetNBV" : "",
        "salePrice" : ""
    },
    {
        "id" : "jfkhkdafhn",
        "sapAssetNumber" : "",
        "isAlreadyDisposed" : "",
        "assetDescription" : "",
        "assetNBV" : "",
        "salePrice" : ""
    },
    {
        "id" : "kjdsaflkadjsf",
        "sapAssetNumber" : "",
        "isAlreadyDisposed" : "",
        "assetDescription" : "",
        "assetNBV" : "",
        "salePrice" : ""
    },
    {
        "id" : "",
        "sapAssetNumber" : "",
        "isAlreadyDisposed" : "",
        "assetDescription" : "",
        "assetNBV" : "500",
        "salePrice" : "500"
    }
];

class Example extends React.Component {
  constructor() {
   super();
  
    setTimeout(() => {
     console.log('changed');
      rows[0].sapAssetNumber = 'meow'
    }, 5000);
  }
  
 render() {
   return <ReactDataGrid
        columns={cols}
        rowGetter={(i) => rows[i]}
        rowsCount={10}
      />;
  }
}

ReactDOM.render(<Example />, document.querySelector("#app"))
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

.done {
  color: rgba(0, 0, 0, 0.3);
  text-decoration: line-through;
}

input {
  margin-right: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-data-grid/6.1.0/react-data-grid.min.js"></script>

<div id="app"></div>
DrogoNevets
  • 1,456
  • 3
  • 18
  • 34

2 Answers2

1

the rows variable is a global variable in your file. After 5 seconds the row variable has changed,but, because the row variable is neither maintained by Example component state nor is a prop to the Example component, the change is not tracked by the Example component life cycle methods. Therefore the render method of the Example component is not called when the rows variable changes and thus ReactDataGrid is not getting the updated values.

try maintaining the rows variable in the state of Example component. like this-

let cols = [
    {
      key: 'sapAssetNumber',
      name: 'SAP Asset number',
      editable: false
    },
    {
      key: 'assetDescription',
      name: 'Description',
      editable: false
    },
    {
      key: 'assetNBV',
      name: 'Asset NBV',
      editable: false
    },
    {
      key: 'salePrice',
      name: 'Sale price',
      editable: false
    }
  ];

  let rows = [
      {
          "id" : "0",
          "sapAssetNumber" : "woof",
          "isAlreadyDisposed" : "",
          "assetDescription" : "test",
          "assetNBV" : "100",
          "salePrice" : "100"
      },
      {
          "id" : "0",
          "sapAssetNumber" : "",
          "isAlreadyDisposed" : "",
          "assetDescription" : "test",
          "assetNBV" : "100",
          "salePrice" : "100"
      },
      {
          "id" : "this",
          "sapAssetNumber" : "is",
          "isAlreadyDisposed" : "a",
          "assetDescription" : "test",
          "assetNBV" : "",
          "salePrice" : ""
      },
      {
          "id" : "jfkhkdafhn",
          "sapAssetNumber" : "",
          "isAlreadyDisposed" : "",
          "assetDescription" : "",
          "assetNBV" : "",
          "salePrice" : ""
      },
      {
          "id" : "kjdsaflkadjsf",
          "sapAssetNumber" : "",
          "isAlreadyDisposed" : "",
          "assetDescription" : "",
          "assetNBV" : "",
          "salePrice" : ""
      },
      {
          "id" : "",
          "sapAssetNumber" : "",
          "isAlreadyDisposed" : "",
          "assetDescription" : "",
          "assetNBV" : "500",
          "salePrice" : "500"
      }
  ];

  class Example extends React.Component {
    constructor() {
        super();

        this.state={rows:rows}


    }

    componentDidMount = () =>{
        const context =  this;
        setTimeout(() => {
            rows[0].sapAssetNumber = 'meow'
            context.setState({rows});
      }, 5000);
    }

      render() {
        return <ReactDataGrid
          columns={cols}
          rowGetter={(i) => rows[i]}
          rowsCount={10}
        />;
    }
  }

  ReactDOM.render(<Example />, document.querySelector("#app"));

please read this for clarity on component state :-https://reactjs.org/docs/faq-state.html

please read this to see when is the render method called:-https://lucybain.com/blog/2017/react-js-when-to-rerender/

Hope it solves the issue!

Ayesha Mundu
  • 1,075
  • 2
  • 11
  • 18
  • I apprceiate the info, I am aware of it, and in my real life example the rows are props but one gets the same behaviour. There are a number of hacks to get it working that exist, alas your suggestion doesn't actually fix the issue – DrogoNevets May 10 '19 at 11:20
  • is the render method being called after prop change? – Ayesha Mundu May 10 '19 at 11:24
1

After consulting the issues in react-data-grid via GitHub I used a solution provided there.

then one need just call this.refresh(). It's not pretty but appears to be a hole in RDG

getRowCount() {
    let count = this.props.rows.length;
    if(this.state.refresh && count > 0) {
      count--; // hack for update data-grid
      this.setState({
        refresh: false
      });
    }

    return count;
  }

refresh() {
    this.setState({
      refresh: true
    });
  }
DrogoNevets
  • 1,456
  • 3
  • 18
  • 34