React ReRender Issue
Я создаю веб-приложение, которое позволит пользователю перетаскивать несколько частей на экране, каждый из которых содержит отдельные конкретные данные. Если пользователь захочет добавить больше элементов на экран, он просто нажмет кнопку, и появится другой элемент. Я использовал библиотеку React DND (Drag and Drap), чтобы отделить мои компоненты, и до сих пор это работало нормально. Проблема заключается в динамической возможности добавления большего количества элементов на экране. В настоящее время (в дочернем коде ниже) я получаю старый объект состояния, выполняю поверхностную копию, объединяю вновь созданный объект с ранее существующим объектом состояния и обновляю состояние по завершении. Но каждый раз, когда я выполняю эту операцию, все работает нормально (новые фрагменты генерируются на экране), пока я не перейду, чтобы переместить новый фрагмент, и я получаю следующую ошибку:
Невозможно обновить во время существующего перехода состояния (например, в
render
). Методы рендеринга должны быть чистой функцией реквизита и состояния.
Как мне выйти из этой ошибки и получить обновление объекта состояния.
Примечание. Кнопка (на снимке экрана ниже) показывает текущий счетчик количества объектов в объекте State. Итак, ниже я добавил 7 объектов в штат
Снимок экрана приложения: родитель:
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);
1 ответ
Похоже, что проблема может лежать внутри вашего компонента "Студент". Запуск вышеуказанного кода без компонента "Студент" (так как он не размещен) работает нормально. Если вы еще не решили эту проблему, пожалуйста, также отправьте box1.js.