React重新渲染问题

5
我正在创建一个Web应用程序,允许用户在屏幕上拖放多个带有各自特定数据的零件。如果用户想要在屏幕上添加更多的零件,则只需单击一个按钮,另一个零件将出现。我使用了React DND(拖放)库来保持我的组件解耦,到目前为止这样做得很好。问题出在动态添加更多零件的功能上。目前(在下面的Child代码中),我正在获取旧的状态对象,执行浅复制,并将新创建的对象与现有状态对象合并,完成后更新状态。但是,每次执行此操作时,一切正常(在屏幕上生成新零件),直到我尝试移动新零件时,就会出现以下错误:

无法在现有状态转换期间(比如在render中)进行更新。 渲染方法应该是props和state的纯函数。

我应该如何摆脱这个错误,并使状态对象更新。 备注:截图中的按钮显示State对象中对象的当前计数。因此,我向State中添加了7个对象。
应用程序截图: enter image description here 父组件:
  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);

孩子:

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);

当您开始拖动该部件或尝试放置该部件时,是否出现错误?如果是前者,您可以发布学生组件吗? - Ben Hare
1个回答

0

看起来问题可能出在你的“Student”组件内。如果不包含“Student”组件(因为它没有发布),运行上述代码是正常的。如果你还没有解决这个问题,请同时发布box1.js。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接