Ciao a tutti,
in breve sono alle prese con un paio di componenti React per testare un comportamento specifico.
Il primo chiama un servizio e scarica cosi una lista di documenti in streaming (uno alla volta).
Man mano che arrivano documenti, il componente dovrebbe triggerare il popolamento di una riga DataTable (il secondo componente).
Si consideri che i documenti in arrivo potrebbero essere un numero elevato a piacere.
E che si vuole popolare la tabella nel DOM man mano che arrivano i documenti.
Un primo approccio era di avere uno state, con la lista totale dei documenti, ad ogni documento in arrivo, un setState aggiorna la lista aggiungendo il nuovo arrivo, e fa ri-renderizzare la tabella.
Funzionava, ma se i docs restituiti dal servizio fossero tanti, il DataTable verrebbe virtualmente ri-renderizzato ricaricando nel Virtual-DOM tutti i dati da capo ogni volta che arriva un documento. Il che costituirebbe un collo di bottiglia per le prestazioni.
Il mio secondo approccio: non memorizzare la lista intera, ma fare un setState solo con il documento in arrivo. Assicurarmi che il ri-render della tabella non venga effettuato in caso di nuovi arrivi usando il metodo shouldComponentUpdate(). Ma allo stesso tempo prendere il documento e aggiungerlo tramite metodo nativo di DataTable chiamato in componentDidUpdate().
il mio PROBLEMA e' che il setState che corrisponde ad un nuovo arrivo, non triggera nulla, mettendo un punto di debug nel metodo shouldComponentUpdate() l'esecuzione non si ferma. In console non vedo errori. Se metto un punto di debug al momento di questo setState, si vede che viene eseguito e il nuovo documento esiste ma poi non avviene nessun aggiornamento del componente DTable.
Gli altri setState lavorano tutti.
Grazie per l'eventuale interesse.
Scrivo qui i due componenti.
Non credo serva altro.
Le varie importazioni le ho verificate e puntano correttamente.
Qui allego anche dei console.log prodotti al refresh pagina.
![1733580428249.webp 1733580428249.webp](https://forum.tomshw.it/data/attachments/440/440112-652eea3d8b404ee23ae0c41cfa0bf672.jpg?hash=mxjbLOQYY4)
Si vede che il metodo shouldComponentUpdate non viene chiamato affatto, quando eseguiamo il setState "streaming". Cio' avverrebbe alla terza riga di conosole.log dove stampo il documento in arrivo.
in breve sono alle prese con un paio di componenti React per testare un comportamento specifico.
Il primo chiama un servizio e scarica cosi una lista di documenti in streaming (uno alla volta).
Man mano che arrivano documenti, il componente dovrebbe triggerare il popolamento di una riga DataTable (il secondo componente).
Si consideri che i documenti in arrivo potrebbero essere un numero elevato a piacere.
E che si vuole popolare la tabella nel DOM man mano che arrivano i documenti.
Un primo approccio era di avere uno state, con la lista totale dei documenti, ad ogni documento in arrivo, un setState aggiorna la lista aggiungendo il nuovo arrivo, e fa ri-renderizzare la tabella.
Funzionava, ma se i docs restituiti dal servizio fossero tanti, il DataTable verrebbe virtualmente ri-renderizzato ricaricando nel Virtual-DOM tutti i dati da capo ogni volta che arriva un documento. Il che costituirebbe un collo di bottiglia per le prestazioni.
Il mio secondo approccio: non memorizzare la lista intera, ma fare un setState solo con il documento in arrivo. Assicurarmi che il ri-render della tabella non venga effettuato in caso di nuovi arrivi usando il metodo shouldComponentUpdate(). Ma allo stesso tempo prendere il documento e aggiungerlo tramite metodo nativo di DataTable chiamato in componentDidUpdate().
il mio PROBLEMA e' che il setState che corrisponde ad un nuovo arrivo, non triggera nulla, mettendo un punto di debug nel metodo shouldComponentUpdate() l'esecuzione non si ferma. In console non vedo errori. Se metto un punto di debug al momento di questo setState, si vede che viene eseguito e il nuovo documento esiste ma poi non avviene nessun aggiornamento del componente DTable.
Gli altri setState lavorano tutti.
Grazie per l'eventuale interesse.
Scrivo qui i due componenti.
Non credo serva altro.
Le varie importazioni le ho verificate e puntano correttamente.
JavaScript:
import React from 'react';
import oboe from 'oboe';
import DTable from '../DTable/DTable.js';
import columns from '../../models/customer/DTable/columns.js'
class GlobalServices extends React.Component {
constructor(props) {
super(props);
this.state = {
customers: {
chunk: null,
state: 'tostream',
error: null
}
}
this.getAllCustomers = this.getAllCustomers.bind(this);
}
getAllCustomers() {
this.setState(() => ({
customers: {
chunk: null,
state: 'tostream',
error: null
}
}));
oboe({
url: `${window.origin}/customers/list`,
method: 'GET'
}).node('!*', doc => {
this.setState(() => ({
customers: {
chunk: doc,
state: 'streaming',
error: null
}
}));
}).done(() => {
this.setState(() => ({
customers: {
chunk: null,
state: 'streamed',
error: null
}
}));
}).fail((error) => {
this.setState(() => ({
customers: {
chunk: null,
state: 'interrupted',
error: error.message || 'Generic error'
}
}));
});
}
componentDidMount() {
this.getAllCustomers();
}
render() {
return <DTable update={this.state.customers} columns={columns} />;
}
}
export default GlobalServices;
JavaScript:
import './DTable.css';
import React from 'react';
import DataTable from 'datatables.net-react';
import DT from 'datatables.net-bs5';
import 'datatables.net-responsive-bs5';
DataTable.use(DT);
class DTable extends React.Component {
constructor(props) {
super(props);
this.tableRef = React.createRef();
}
shouldComponentUpdate(nextProps, nextState) {
return ['tostream', 'interrupted'].includes(nextProps.update.state);
}
componentDidUpdate() {
const state = this.props.update.state;
const chunk = this.props.update.chunk;
if (state === 'streaming') {
const table = this.tableRef.current.dt();
table.row.add(chunk).draw();
}
}
render() {
const options = {
paging: true,
searching: true,
responsive: true,
language: {
url: '//cdn.datatables.net/plug-ins/1.13.6/i18n/it-IT.json', // Carica la lingua italiana
}
};
const table =
<DataTable
ref={this.tableRef}
columns={this.props.columns}
options={options}
className="table table-striped display responsive nowrap"
/>
;
return table;
}
}
export default DTable;
Qui allego anche dei console.log prodotti al refresh pagina.
![1733580428249.webp 1733580428249.webp](https://forum.tomshw.it/data/attachments/440/440112-652eea3d8b404ee23ae0c41cfa0bf672.jpg?hash=mxjbLOQYY4)
Si vede che il metodo shouldComponentUpdate non viene chiamato affatto, quando eseguiamo il setState "streaming". Cio' avverrebbe alla terza riga di conosole.log dove stampo il documento in arrivo.
Ultima modifica: