Respond to a ReRender Problem

I am creating a web application that will allow the user to drag and drop several fragments on the screen, each of which contains individual specific data. If the user wants to add more shapes to the screen, they simply click a button and another part appears. I used the React DND (Drag and Drap) library so that my components are decoupled and so far this has worked fine. The problem is the dynamic function of adding more elements to the screen. Currently (in the Child code below) I get the old state object by making a shallow copy and combining the newly created object with an existing state object and updating the state when it is finished. But every time I perform this operation, everything works fine (new fragments created on the screen) until I go over,to move the new fragment, and I made a mistake in the following error:

Unable to update during an existing state transition (for example, within render). Imaging methods should be a pure function of props and status.

How can I get rid of this error and have an update status object.

Note. The button (in the screenshot below) shows the current counter of the number of objects in the State object. So below I added 7 objects to state

Application Screenshot:   enter image description here Parent:

  import React, { Component, PropTypes } from 'react';
    import Header from '../../components/Header/header';
    import Footer from '../../components/Footer/footer';
    import Student from '../../components/box1/box1';
    import Box from '../../components/box2/box2';
    import { DragDropContext } from 'react-dnd';
    import HTML5Backend from 'react-dnd-html5-backend';
    require('./home.css');


var Home = React.createClass({
  getDefaultProps: function(){

    return{ count: 3 }  
  },

  getInitialState: function(){
     return{ count: this.props.count }
  },

  add: function(){
     this.setState({ count: this.state.count + 1 });
  },

  render() {

    return (
        <div id="main">
              <Box count = {this.state.count}/>
              <button count = {this.state.count} onClick = {this.add} > {this.state.count} </button>
          </div>

    );
  }
});

export default DragDropContext(HTML5Backend)(Home);

Child:

import React from 'react';
var ItemTypes = require('../box1/Constants').ItemTypes;
var DropTarget = require('react-dnd').DropTarget;
var Student = require('../box1/box1');
import update from 'react/lib/update';


require('./box2.css');

var BoxSource = {
  drop: function (props, monitor, component) {  
    const item = monitor.getItem();
    console.log(item);
    const delta = monitor.getDifferenceFromInitialOffset();
    const left = Math.round(item.left + delta.x);
    const top = Math.round(item.top + delta.y);
    const id = item.id;

    component.move(id, left, top);
       }
};

function collect(connect, monitor) {
  return {
    connectDropTarget: connect.dropTarget(),
    didDrop: monitor.didDrop(),
    source: monitor.getSourceClientOffset(),
    item: monitor.getItem(),
    drop: monitor.didDrop(),
    result: monitor.getDropResult()
  };
}

var box2 = React.createClass({

    getInitialState: function() {
    return  { Students: {
        '0': { top: 20, left: 80 },
        '1': { top: 180, left: 20 },
        '2': { top: 130, left: 20 },

      }
    };
  },


componentWillReceiveProps: function(nextProps) {
     var i = this.props.count;
     console.log(this.state.Students);
     var obj = update(this.state,{ 

      Students:{ 
                $merge:{
                  [i]:{
                    top: 10,
                     left:10 
                    }
                  }
                }        
             });

    this.setState(obj);
  },

  move: function(id,left,top){
     this.setState(update(this.state,{
          Students:{ 
               [id]:{
                    $merge:{
                     left:left,
                     top: top
                    }
                  }
                }
            }));
  },

  render:function() {
    const { Students } = this.state;
    var connectDropTarget = this.props.connectDropTarget;
    return connectDropTarget(
      <div id = "box">
            {Object.keys(Students).map(key =>{
                const { left, top, title } = Students[key];
                 return(
                            <Student key = {key} id = {key} left = {left}
                            top = {top}> </Student>
                         );})}
      </div>
    );
  }
});

module.exports = DropTarget(ItemTypes.STUDENT, BoxSource, collect)(box2);
+4
source share
1 answer

, "". "" ( ) . , , box1.js.

0

All Articles