私は、ユーザーが画面上で複数の部分をドラッグアンドドラッグできるようにする Web アプリを作成しています。それぞれが個々の特定のデータを保持しています。ユーザーが画面にピースを追加したい場合は、ボタンをクリックするだけで別のピースが表示されます。React DND (Drag and Drap) ライブラリを使用してコンポーネントを分離した状態に保ちましたが、これまでのところ問題なく機能しています。問題は、画面にピースを追加する動的機能にあります。現在 (以下の子コード)、古い状態オブジェクトを取得し、浅いコピーを実行し、新しく作成されたオブジェクトを既存の状態オブジェクトとマージし、終了時に状態を更新しています。ただし、この操作を実行するたびに、新しいピースを移動して次のエラーが表示されるまで、すべて正常に動作します (画面上に新しいピースが生成されます)。
既存の状態遷移中 ( 内など) は更新できません
render
。Render メソッドは props と state の純粋な関数であるべきです。
このエラーから抜け出し、状態オブジェクトを更新するにはどうすればよいですか。
注: ボタン (下のスクリーンショット) は、State オブジェクト内のオブジェクトの現在の数を示します。以下では、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);