2014-01-20 11 views
60

Ich bin auf der Suche nach Möglichkeiten, unendliches Scrollen mit React zu implementieren. Ich bin auf react-infinite-scroll gestoßen und fand es ineffizient, da es nur Knoten zum DOM hinzufügt und sie nicht entfernt. Gibt es eine bewährte Lösung mit React, die eine konstante Anzahl von Knoten im DOM hinzufügt, entfernt und erhält.Unendliche Scrolling mit React JS

Hier ist das jsfiddle Problem. In diesem Problem möchte ich nur 50 Elemente im DOM zu einer Zeit haben. Andere sollten geladen und entfernt werden, wenn der Benutzer nach oben und unten scrollt. Wir verwenden React wegen seiner Optimierungsalgorithmen. Jetzt konnte ich keine Lösung für dieses Problem finden. Ich bin auf airbnb infinite js gestoßen. Aber es ist mit Jquery implementiert. Um diese Airbnb-Endlos-Scroll zu verwenden, muss ich die React-Optimierung verlieren, die ich nicht machen möchte.

Beispielcode i scroll hinzufügen möchten (hier i alle Elemente bin Laden. Mein Ziel nur 50 Gegenstände auf einmal zu laden ist)

/** @jsx React.DOM */ 

var Hello = React.createClass({ 
    render: function() { 
     return (<li>Hello {this.props.name}</li>); 
    } 
}); 

var HelloList = React.createClass({ 
    getInitialState: function() {        
     var numbers = []; 
     for(var i=1;i<10000;i++){ 
      numbers.push(i); 
     } 
     return {data:numbers}; 
    }, 

    render: function(){ 
     var response = this.state.data.map(function(contact){   
      return (<Hello name="World"></Hello>); 
     }); 

     return (<ul>{response}</ul>) 
    } 
}); 

React.renderComponent(<HelloList/>, document.getElementById('content')); 

Hilfe der Suche ...

Antwort

46

Grundsätzlich Beim Scrollen möchten Sie entscheiden, welche Elemente sichtbar sind und dann erneut angezeigt werden, um nur diese Elemente anzuzeigen, mit einem einzelnen Abstandselement oben und unten, um die Offscreen-Elemente darzustellen.

Vjeux machte eine Geige hier, die Sie betrachten können:

http://jsfiddle.net/vjeux/KbWJ2/9/

Beim Scrollen es

Funktion displayStart..displayEnd nur die Zeilen im Bereich zeigt das
scrollState: function(scroll) { 
    var visibleStart = Math.floor(scroll/this.state.recordHeight); 
    var visibleEnd = Math.min(visibleStart + this.state.recordsPerBody, this.state.total - 1); 

    var displayStart = Math.max(0, Math.floor(scroll/this.state.recordHeight) - this.state.recordsPerBody * 1.5); 
    var displayEnd = Math.min(displayStart + 4 * this.state.recordsPerBody, this.state.total - 1); 

    this.setState({ 
     visibleStart: visibleStart, 
     visibleEnd: visibleEnd, 
     displayStart: displayStart, 
     displayEnd: displayEnd, 
     scroll: scroll 
    }); 
}, 

und dann machen ausführt.

Sie könnten auch interessiert sein an ReactJS: Modeling Bi-Directional Infinite Scrolling.

+1

Dies ist eine großartige Technik ... thx! Es schlägt jedoch fehl, wenn die recordHeight für jede Zeile unterschiedlich ist. Ich experimentiere mit einer Lösung für diese Situation. Ich werde es posten, wenn ich es zur Arbeit bekomme. – manalang

+0

@manalang Haben Sie für jede Zeile eine Lösung für unterschiedliche Höhen gefunden? – Exception

+0

@manalang Ich zweite das - noch Glück? –

16

Schauen Sie sich unsere Reaktion Infinite Libary:

https://github.com/seatgeek/react-infinite

-Update Dezember 2016

Ich habe eigentlich mit worden react-virtualized in vielen meiner Projekte vor kurzem und feststellen, dass sie die Mehrheit deckt von Anwendungsfällen viel besser. Beide Bibliotheken sind gut, es hängt davon ab, was genau Sie suchen. Zum Beispiel unterstützt reaktiv-virtualisiert JIT-Messung mit variabler Höhe über eine HOC-Adresse CellMeasurer, hier beispielhaft https://bvaughn.github.io/react-virtualized/#/components/CellMeasurer.

+0

@jos: Verwenden Sie diese Bibliothek. Es entfernt/hängt DOM-Knoten so an, wie sie im Ansichtsfenster erscheinen. – williamle8300

+7

Diese Bibliothek funktioniert nur, wenn Sie die Höhen Ihrer Elemente vor dem Rendern kennen. – Druska

+0

@Druska, Technisch ja, aber Sie können das Fenster auch als Scroll-Container verwenden, indem Sie die Option useWindowAsScrollContainer verwenden. – HussienK