Search code examples
reactjsreact-dnd

React Js, How can I save multiple data in onClick?


I have table, which is positioned by x value and y value. These values are saved in database. I am using react dnd to positioning these table.

What I am trying to do now is that save all tables position at one click. To do that I made code like below..

constructor() {
 super();
 this.state = {
   tables: []
 }}

saveTables() {
 const { state, dispatch, tables } = this.props;
 this.state.tables.map((table) => {
  const data ={
    id: table.id,
    x: table.x,
    y: table.y,
  }
  dispatch(Actions.save(this.props.tables.channel, data));
 })
}

<button onClick={this.saveTables}>Save</button>

So when component is mounted, i get all information of table into this.state.tables. So with saveTables() function, what I am trying to do is that by mapping this.state.tables dispatch actions to save position of x and y for every single table. However, it triggers error that TypeError: action is undefined

Is it possible to do it like above? or is there any other approaches to save all tables data in one click?

Thanks in advance..

--Edit full error

TypeError: action is undefined[Learn More] app.js:54241:1 routerMiddleware/</</< http://localhost:4000/js/app.js:54241:1 saveTables/< http://localhost:4000/js/app.js:73190:9 map self-hosted saveTables http://localhost:4000/js/app.js:73184:7 bound saveTables self-hosted bound bound saveTables self-hosted ReactErrorUtils.invokeGuardedCallback http://localhost:4000/js/app.js:45316:7 executeDispatch http://localhost:4000/js/app.js:39166:5 executeDispatchesInOrder http://localhost:4000/js/app.js:39189:5 executeDispatchesAndRelease http://localhost:4000/js/app.js:38581:5 executeDispatchesAndReleaseTopLevel http://localhost:4000/js/app.js:38592:10 forEach self-hosted forEachAccumulated http://localhost:4000/js/app.js:50930:5 EventPluginHub.processEventQueue http://localhost:4000/js/app.js:38795:7 runEventQueueInBatch http://localhost:4000/js/app.js:45345:3 ReactEventEmitterMixin.handleTopLevel http://localhost:4000/js/app.js:45356:5 handleTopLevelImpl http://localhost:4000/js/app.js:45438:5 TransactionImpl.perform http://localhost:4000/js/app.js:50185:13 ReactDefaultBatchingStrategy.batchedUpdates http://localhost:4000/js/app.js:45084:14 batchedUpdates http://localhost:4000/js/app.js:48223:10 ReactEventListener.dispatchEvent http://localhost:4000/js/app.js:45513:7 bound


Solution

  • You can map all the data you need to save and then dispatch an action (this will be more efficient as your app will only run the rendering routine once).

    saveTables() {
      const { dispatch, tables } = this.props;
      const tableData = tables.map(table => ({
        id: table.id,
        x: table.x,
        y: table.y,
      });
      dispatch(Actions.save(tables.channel, tableData));
    }
    

    tableData should then be an array like:

    [{id, x, y}, {id, x, y} ...]
    

    Of course you will have to modify the action/reducer to deal with an array of all the data.

    As for the action you need to provide the code where the error happens (not just the stack trace), but it will probably be hard to know without a running example.