2016-06-29 6 views
0

In AngularJS können Sie "Filter" verwenden, um die Ergebnisse einer ng-repeat wie so zu verengen:In ReactJS gibt es eine Möglichkeit, gerenderte Ergebnisse zu filtern, die über iteriert werden?

<div ng-repeat="item in items | filter: x"> 

Derzeit bin ich mit Array.map() mehr Elemente in einem Array in ReactJS zu machen und ich frage mich, wie genau die Funktionalität von Angulars ng-repeat-Filter in ReactJS repliziert werden kann.

Dies ist meine aktuelle Methode, die ich ein paar Blog-Posts machen bin mit:

renderBlogs() { 
     return this.props.blogs.map((blog) => { 
     return (
      <div key={blog.id}> 
      <Link to={`blogs/${blog.id}`}> 
       <img src={blog.image_url} /> 
       <h1>Author</h1> 
       <p>{blog.author}</p> 
       <h1>Title</h1> 
       <p>{blog.topic}</p> 
      </Link> 
      </div> 
     ) 
     }) 
    } 

Im Hoffnung, nur ein Eingabefeld hat, das die Ergebnisse meiner Iteration filtert, wenn das Eingabefeld ändert. Gibt es NPM-Module, die dabei helfen könnten oder ein typischer Ansatz zur Lösung dieses Problems?

Dank

+0

Map gibt Ihnen eine Funktion pro Eintrag, so dass Sie leicht eine Logik in den Callback einfügen können, um das Element nur zurückzugeben, wenn es Ihre Bedingung erfüllt, oder verwenden Sie _.filter. – lux

+1

Im Gegensatz zu anderen Frameworks, die unbenannt bleiben sollen, empfiehlt React, JavaScript zu verwenden. Sie sollten in Erwägung ziehen, die Standardbibliothek von JS zu erlernen, insbesondere [Array.prototype.filter] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter), die werde (halb) was du willst hier machen. Es gibt absolut keinen Grund, eine weitere Bibliothek in den Mix aufzunehmen. 'lodash.filter' wäre in Ordnung, aber nur, wenn Ihre Eingabe' Objekt | ist Array' anstatt ein Array zu sein. Sie wissen, dass dieses Objekt ein Array ist; keine Notwendigkeit, lodash zu erreichen. –

Antwort

1

Anders als Angular, reagiert nicht für Dinge zu tun, wie das seine eigene Primitiven, und statt das Rad neu zu erfinden, es verlässt sich nur auf JS.

In JavaScript können Sie ein Array filterfilter durch den Aufruf und eine Funktion bereitstellt, die jede einzelne Position nehmen und sagen, ob es schließen oder nicht:

[1, -2, 3, -4, 5, -6].filter(x => x > 0) // [1, 3, 5] 

Filter und Karte auch kombiniert werden können:

[1, -2, 3, -4, 5, -6].filter(x => x > 0).map(x => x * 2) // [2, 6, 10] 

Nichts wird sogar ändern, wenn Sie eine React Komponente von Karte zurückgeben, es ist immer noch die JS-Filter + Karte:

return this.props.blogs.filter(blog => { 
    return true; // place your actual check here 
}).map((blog) => { 
    return (
    <div key={blog.id}> 
     <Link to={`blogs/${blog.id}`}> 
     <img src={blog.image_url} /> 
     <h1>Author</h1> 
     <p>{blog.author}</p> 
     <h1>Title</h1> 
     <p>{blog.topic}</p> 
     </Link> 
    </div> 
) 
}) 
0

Mit React benötigt die Lösung mehr Javascript, aber lassen Sie sich davon nicht abschrecken.

Es gibt viele Möglichkeiten, die Sie erreichen können, was Sie wollen, aber ich denke, Sie Ihre Texteingabe in den Zustand Ihrer Komponente oder den Zustand Ihrer Anwendung mit dem onChange Haken Draht sollte:

<input onChange={changeHandler} .. /> 

Implementieren Sie Ihre changeHandler(..) so, dass sie setState(..) aufruft, um das Modell zu aktualisieren, in dem der eingegebene Text gespeichert wird. Dadurch werden die Komponenten und untergeordneten Komponenten neu gerendert, sodass Sie Ihre renderBlogs(..)-Funktion aufrufen können.

Sie müssen eine Prädikatfunktion entwickeln, die bestimmt, ob ein Blogpost basierend auf einigen Kriterien angezeigt oder ausgeblendet wird. Ich würde dies in eine Hilfsfunktion abstrahieren, aber die Einzelheiten der Implementierung liegen ganz bei Ihnen. Sie sollten es wahrscheinlich aus einer Kombination aus dem Text, den Sie in Ihrem Modell haben, und dem innerHTML der Textelemente in Ihrem Markup ableiten.

Dann würde ich die Return-Anweisung von renderBlogs(..) refaktorieren, um dieses Prädikat zu nennen, bevor Sie eine Ihrer Blog-Komponenten zurückgeben.

renderBlogs() { 
    return this.props.blogs.map((blog) => { 
    return this.predicateFn(blog) 
     ? this.renderBlog(blog) 
     : null 
    }).filter(Boolean); 
} 

ich auch das Markup für Ihren Blog-Post in seine eigene Komponente oder als Methode auf diese Komponente ... so etwas wie renderBlog(..) abstrahiert entfernt würde empfehlen.

Viel Glück!