Ich bin ziemlich neu zu ReactJS und meine Probleme sind ziemlich ungewöhnlich, kann auftreten, einfach weil ich Dinge nicht so implementieren, wie sie sein sollen.Reagieren Js Komponente Rendering nur einmal nach Zustandsänderung
Also im Prinzip funktionierte das vorher gut, aber ich musste einige neue Funktionen hinzufügen, und ... nun, etwas ist aus.
Zu Beginn - ConvFrame
ist Top-Komponente, auf der Seite an der Spitze erscheinen, und es besteht aus ConvForm
Komponente (neue Abfragen hinzufügen) und ConvList
wo nicht zugeordnet und neue Anrufe gehen. Die ConvList
hat hier ID und Key von 1.
Es gibt auch Liste der Arbeitnehmer unter, die sie verwenden ConvForm
nur die Felder selbst Dropzones sind, die schnell neuen Anruf Aufgaben zuweisen lassen. Die ConvList
hier haben Id und Key gleich ID des Worker.
Da der ConvList
gerendert wird, fragt er den Server nach Jobs in der Liste ab. Und das funktioniert für alle gut. Es scheint jedoch ein seltsames Problem zu geben, wenn ein neuer Artikel über ConvForm
hinzugefügt wird. Er fordert handleCommentSubmit()
Funktion ruft this.loadCommentsFromServer();
(dumm, ich weiß!) Und dann für Datensätze neuen Staat setzt this.setState({records: data});
Als erster Datensatz die /api/zlecenia
hinzugefügt wird, wird zweimal aufgerufen. Einmal von der loadCommentsFromServer()
innerhalb ConvFrame
und zweiten Mal von innerhalb ConvList
. Hinzufügen von zweiten Datensatz per Formular ruft es einmal auf, die Komponente scheint nicht auf die Zustandsänderung zu reagieren. Etwas ist schlecht implementiert, denke ich.
Hier ist der Quellcode: Conversations.js
//For dragging
var placeholder = document.createElement("div");
placeholder.className = "placeholder";
var dragged;
var over;
/**
* Conversation
* Should be used for listing conversation blocks, adds class based on age of task.
* Detects drag events, renders block, calls dragEnd function to append block to new
* location and uses props.OnDrop function to pass id of element and target id of worker
*/
window.Conversation = React.createClass({
dynamicClass: function() {
return "convo " + this.props.delay;
},
dragStart: function (e) {
dragged = e.currentTarget;
over = null;
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData("text/html", e.currentTarget);
},
dragEnd: function (e) {
$(dragged).show();
$(placeholder).remove();
console.log(over, over.className);
if (over && over.className === "candrop") {
var id = Number(dragged.dataset.id);
this.props.onDrop({id: id, target: over.id});
over.appendChild(dragged);
}else{
console.log('returning base:' + over);
$(dragged).parent().append(dragged);
}
},
render: function() {
return (
<div draggable="true" data-id={this.props.id} onDragEnd={this.dragEnd} onDragStart={this.dragStart} className={this.dynamicClass()} >
{this.props.children}
</div>
);
}
});
/**
* ConvList
* Displays conversation dropdown list. I should aim to make it single component, do not repeat for workers.
* Detects dragOver for .candrop and place some funny placeholder. Detect position change from Conversation view
* call master class from parent component and pass data. Detect delete event.
*/
window.ConvList = React.createClass({
getInitialState: function() {
return {data: []};
},
loadConvsFromServer: function() {
$.ajax({
url: baseUrl + '/api/zlecenia',
type: 'GET',
data: {id: this.props.id},
success: function (data) {
this.setState({data: data});
}.bind(this),
error: function (xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
componentDidMount: function() {
this.loadConvsFromServer();
},
dragOver: function (e) {
e.preventDefault();
$(dragged).fadeOut();
if (e.target.className === "candrop") {
if (e.target.className == "placeholder")
return;
over = e.target;
e.target.appendChild(placeholder, e.target);
}
},
updatePosition: function (data) {
console.log('update convo %d for member %e', data.id, data.target);
$.ajax({
url: baseUrl + '/api/zlecenia',
type: 'PUT',
data: {id: data.id, assign: data.target},
success: function (data) {
}.bind(this),
error: function (xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
deleteTask: function (e) {
var taskIndex = parseInt(e.target.value, 10);
console.log('remove task: %d', taskIndex);
$.ajax({
url: baseUrl + '/api/zlecenia/' + taskIndex,
type: 'DELETE',
success: function (data) {
this.loadConvsFromServer();
}.bind(this),
error: function (xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
render: function() {
return (
<div className="convlist" onDragOver={this.dragOver}>
<div className="candrop" id={this.props.id} >{this.props.id}
{this.state.data.map((c) =>
<Conversation onDrop={this.updatePosition} delay={c.delayTime} id={c.id} key={c.id}>
<p className="convTop">{c.formattedTime} | Tel. {c.phone} | {c.name} | Nr.Rej {c.number}</p>
<p>{c.text}</p>
<button className="deleteConv" onClick={this.deleteTask} value={c.id}>x</button>
</Conversation>
)}
</div>
</div>
);
}
});
/**
* ConvForm
* Displays conversation create form. Prepares fields, validates them.
* Call master function to add new record on send.
*/
var ConvForm = React.createClass({
getInitialState: function() {
return {phone: '', name: '', number: '', text: ''};
},
handlePhoneChange: function (e) {
this.setState({phone: e.target.value});
},
handleNameChange: function (e) {
this.setState({name: e.target.value});
},
handleNumberChange: function (e) {
this.setState({number: e.target.value});
},
handleTextChange: function (e) {
this.setState({text: e.target.value});
},
submitForm: function (e) {
e.preventDefault();
var phone = this.state.phone.trim();
var name = this.state.name.trim();
var number = this.state.number.trim();
var text = this.state.text.trim();
if (!text || !phone || !name || !number) {
return;
}
this.props.onConvSubmit({phone: phone, name: name, number: number, text: text});
this.setState({phone: '', text: '', number: '', name: ''});
},
render: function() {
return (
<form className="convForm" onSubmit={this.submitForm}>
<div className="row">
<div className="col-xs-12 col-md-4">
<div className="form-group">
<input
className="form-control"
type="text"
placeholder="Telefon"
value={this.state.phone}
onChange={this.handlePhoneChange}
/>
</div>
</div>
<div className="col-xs-12 col-md-4">
<div className="form-group">
<input
className="form-control"
type="text"
placeholder="Imię i nazwisko"
value={this.state.name}
onChange={this.handleNameChange}
/>
</div>
</div>
<div className="col-xs-12 col-md-4">
<div className="form-group">
<input
className="form-control"
type="text"
placeholder="Nr. rejestracyjny"
value={this.state.number}
onChange={this.handleNumberChange}
/>
</div>
</div>
</div>
<div className="form-group">
<textarea
className="form-control"
type="text"
placeholder="Treść"
value={this.state.text}
onChange={this.handleTextChange}
/>
</div>
<input className="btn btn-success" type="submit" value="Zapisz" />
</form>
);
}
});
/**
* ConvFrame
* Conversation main frame and root functions for both form and conversations listing.
*/
window.ConvFrame = React.createClass({
getInitialState: function() {
return {records: []};
},
loadCommentsFromServer: function() {
$.ajax({
url: baseUrl + '/api/zlecenia',
type: 'GET',
data: {id : 1},
success: function (data) {
this.setState({records: data});
}.bind(this),
error: function (xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
handleCommentSubmit: function (convo) {
$.ajax({
url: baseUrl + '/api/zlecenia',
type: 'POST',
data: convo,
success: function (data) {
this.loadCommentsFromServer();
}.bind(this),
error: function (xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
render: function() {
return (
<div className="add-new">
<div className="row">
<div className="col-xs-12 col-md-12 frame">
<div className="col-xs-12 col-md-7">
<h3>Dodaj nową rozmowę</h3>
<ConvForm onConvSubmit={this.handleCommentSubmit} />
</div>
<div className="col-xs-12 col-md-5">
<ConvList key='1' id='1' data={this.state.records} />
</div>
</div>
</div>
</div>
);
}
});
workers.js
/**
* WorkerList
*
*/
var Worker = React.createClass({
render: function() {
return (
<div>
{this.props.children}
</div>
);
}
});
/**
* WorkerList
*
*/
var WorkerList = React.createClass({
render: function() {
return (
<div className="worker-list">
{this.props.data.map((worker) =>
<Worker id={worker.id} key={worker.id}>
<div className="row">
<div className="col-xs-12 col-md-12 frame">
<div className="col-xs-12 col-md-5">
<h4>{worker.username}</h4>
</div>
<div className="col-xs-12 col-md-7">
<ConvList key={worker.id} id={worker.id} />
</div>
</div>
</div>
</Worker>
)}
</div>
);
}
});
/**
* WorkerForm
*
*/
var WorkerForm = React.createClass({
render: function() {
return (
<div>
</div>
);
}
});
/**
* WorkerFame
*
*/
window.WorkerFrame = React.createClass({
getInitialState: function() {
return {data: []};
},
loadWorkersFromServer: function() {
$.ajax({
url: baseUrl + '/api/pracownicy',
type: 'GET',
success: function (data) {
this.setState({data: data});
}.bind(this),
error: function (xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
componentDidMount: function() {
this.loadWorkersFromServer();
},
handleWorkerSubmit: function (worker) {
$.ajax({
url: baseUrl + '/api/pracownicy',
type: 'POST',
data: worker,
success: function (data) {
this.loadWorkersFromServer();
}.bind(this),
error: function (xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
render: function() {
return (
<div className="add-new">
<div className="row">
<div className="col-xs-12 col-md-12">
<WorkerList data={this.state.data} />
</div>
<div className="col-xs-12 col-md-12">
<WorkerForm onWorkerSubmit={this.handleWorkerSubmit} />
</div>
</div>
</div>
);
}
});
final.js
var DashFrame = React.createClass({
render: function() {
return (
<div>
<ConvFrame/>
<WorkerFrame/>
</div>
);
}
});
ReactDOM.render(
<DashFrame/>,
document.getElementById('dashboard')
);
Irgendwelche Hinweise geschätzt würde. Mein Gehirn kocht.
Haben Sie eine Slogan-Seite dafür? –