2016-08-25 2 views
1

Ich bin neu in Redux und reagieren. Ich versuche, die Sortierung für eine reaktive Komponente zu implementieren, aber soweit ich weiß, dürfen Sie die props in Redux nicht manipulieren. Was ist der richtige Weg, dass reagieren redux in tunWas ist die Redox-Reaktion Weg Requisiten in reagieren Kinder Komponente

Hier meine Komponente

import React, { Component, PropTypes } from 'react'; 
import _ from 'lodash'; 
import { connect } from 'react-redux'; 
import { bindActionCreators } from 'redux'; 

import * as ArticlesActions from '../../actions/ArticlesActions'; 
import { ArticleList } from '../../components'; 

class ArticleListApp extends Component { 

    static propTypes = { 
    articles: PropTypes.array.isRequired, 
    next: PropTypes.string.isRequired, 
    actions: PropTypes.object.isRequired 
    }; 

    componentWillMount() { 
    this.props.actions.fetchArticles('57bde6d6e4b0dc55a4f018e0'); 
    } 

    renderLoadMoreButton() { 
    if (!_.isEmpty(this.props.next)) { 
     return (
     <button type="button" className="btn btn-link center-block" onClick={this.props.actions.fetchMoreArticles.bind(this, this.props.next)}>Load More</button> 
    ); 
    } 

    return ''; 
    } 

    render() { 
    return (
     <div> 
     <ArticleList articles={this.props.articles}/> 
     <div className="row"> 
      <div className="col-md-12 center-block"> 
      {this.renderLoadMoreButton()} 
      </div> 
     </div> 
     </div> 
    ); 
    } 
} 

function mapStateToProps(state) { 
    return { 
    articles: state.articleList.articleList, 
    next: state.articleList.next 
    }; 
} 

function mapDispatchToProps(dispatch) { 
    return { 
    actions: bindActionCreators(ArticlesActions, dispatch) 
    }; 
} 

export default connect(
    mapStateToProps, 
    mapDispatchToProps 
)(ArticleListApp); 

einmal I articles ich passieren, dass zu ArticleList Komponente, die ich denke, es ist eine dump Komponente in redux reagieren

import React, { Component, PropTypes } from 'react'; 

export default class ArticleList extends Component { 
    static propTypes = { 
    articles: PropTypes.array.isRequired 
    } 
    constructor(props, context) { 
    super(props, context); 
    } 

    renderList() { 
    return this.props.articles.map((article) => 
     <tr> 
     <td>{article.title}</td> 
     <td>Author</td> 
     <td>{article.words}</td> 
     <td>ago</td> 
     </tr> 
    ); 
    } 

    sortArticles() { 
    this.props.articles = this.props.articles.sort(); // I'm not allowed to do this. 
    } 

    render() { 
    return (
     <table className="table table-hover"> 
      <thead> 
      <tr> 
       <th>UNPUBLISHED ARTICLES ({this.props.articles.length})</th> 
       <th>AUTHOR</th> 
       <th>WORDS</th> 
       <th onClick={this.sortArticles.bind(this)}>SUBMITTED</th> 
      </tr> 
      </thead> 
      <tbody> 
      {this.renderList()} 
      </tbody> 
     </table> 
    ); 
    } 
} 

In dieser Komponente möchte ich eine Sortierfunktion haben, wo ein Benutzer auf die Spalte klicken und die gesamte Tabelle nach dieser Spalte sortieren kann.

Das Beispiel articles Objekt würde

[{title: 'title', word: 10}, {title: 'title', word: 5}] 
+0

Basierend auf welchem ​​Attribut möchten Sie sie sortieren? 'this.props.articles.sort()' wird nicht funktionieren, weil ein Artikel ein Objekt ist. –

+0

Sorry, ich stelle das nur als Beispiel dar, ich möchte nach einem Attribut sortieren, ich werde die Frage aktualisieren. – toy

Antwort

1

so die Redux Strömung sein Komponente ist eine Aktion aufruft, die das Reduzierstück hören und dadurch den Zustand zu aktualisieren. Jeder Container (Komponente, die in eine Verbindungsfunktion eingeschlossen ist), der diesen Status überwacht, rendert sich selbst mit dem neuen Status.

Also, was Sie hier tun möchten, ist ein Listener, der auf das onClick-Ereignis der Spalte in Ihrer ArticleList-Komponente (dumm Komponente) hört, die eine Funktion für die übergeordnete Komponente, die ArticleListApp (Container oder Smart-Komponente) auslöst). Das führt dazu, dass der Container eine Aktion abfeuert, zum Beispiel props.sortByColumn ('AUTHOR', 'asc'). Diese Aktion sollte in Ihrer Aktionen Datei und wird im Grunde so etwas wie dieses

function sortByColumn(columnName, order) { 
    return { 
     type: 'SORT_BY_COLUMN', 
     columnName: columnName, 
     order: order 
    } 
} 

Die Reducer zu dieser Aktion wird hören definiert werden und wird im Allgemeinen Ihr Geschäft mit den Artikeln aktualisieren, in der neuen Reihenfolge aufgeführt werden.

Wenn diese Aktualisierung stattfindet, wird der Container, der diesen Status überwacht, sich selbst mit dem neuen Status rendern. Sie können Click-Handler in jede Spalte einfügen, in der Sie das übergeordnete Element mit der Spalte aufrufen möchten, nach der es sortieren soll.

Ihre Komponenten werden wie folgt aussehen:

import React, { Component, PropTypes } from 'react'; 
import _ from 'lodash'; 
import { connect } from 'react-redux'; 
import { bindActionCreators } from 'redux'; 

import * as ArticlesActions from '../../actions/ArticlesActions'; 
import { ArticleList } from '../../components'; 

class ArticleListApp extends Component { 

    static propTypes = { 
    articles: PropTypes.array.isRequired, 
    next: PropTypes.string.isRequired, 
    actions: PropTypes.object.isRequired 
    }; 

    componentWillMount() { 
    this.props.actions.fetchArticles('57bde6d6e4b0dc55a4f018e0'); 
    } 

    renderLoadMoreButton() { 
    if (!_.isEmpty(this.props.next)) { 
     return (
     <button type="button" className="btn btn-link center-block" onClick={this.props.actions.fetchMoreArticles.bind(this, this.props.next)}>Load More</button> 
    ); 
    } 

    return ''; 
    } 

    render() { 
    return (
     <div> 
     <ArticleList articles={this.props.articles} 
        handleSortByCol={this.props.sortByColumn(columnName, sortOrder)} /> 
     <div className="row"> 
      <div className="col-md-12 center-block"> 
      {this.renderLoadMoreButton()} 
      </div> 
     </div> 
     </div> 
    ); 
    } 
} 

function mapStateToProps(state) { 
    return { 
    articles: state.articleList.articleList, 
    next: state.articleList.next 
    }; 
} 

function mapDispatchToProps(dispatch) { 
    return { 
    actions: bindActionCreators(ArticlesActions, dispatch) 
    }; 
} 

export default connect(
    mapStateToProps, 
    mapDispatchToProps 
)(ArticleListApp); 

Und Ihre andere stumme Komponente wird:

import React, { Component, PropTypes } from 'react'; 

export default class ArticleList extends Component { 
    static propTypes = { 
    articles: PropTypes.array.isRequired 
    } 
    constructor(props, context) { 
    super(props, context); 
    } 

    renderList() { 
    return this.props.articles.map((article) => 
     <tr> 
     <td>{article.title}</td> 
     <td>Author</td> 
     <td>{article.words}</td> 
     <td>ago</td> 
     </tr> 
    ); 
    } 

    sortArticles() { 
    this.props.handleSortByCol('author', 'asc'); 
    } 

    render() { 
    return (
     <table className="table table-hover"> 
      <thead> 
      <tr> 
       <th>UNPUBLISHED ARTICLES ({this.props.articles.length})</th> 
       <th>AUTHOR</th> 
       <th>WORDS</th> 
       <th onClick={this.sortArticles.bind(this)}>SUBMITTED</th> 
      </tr> 
      </thead> 
      <tbody> 
      {this.renderList()} 
      </tbody> 
     </table> 
    ); 
    } 
1

Wenn ich richtig verstehe, dann gibt es zwei Möglichkeiten, um dies zu realisieren:

  1. Artikel sollten im Reducer gespeichert werden, sortiert oder nicht sortiert, abhängig von der Benutzerinteraktion. Technisch geschieht dies, indem die Aktion "sort" ausgelöst wird (durch den Container) und dann ein Reduzierer, der dieses Ereignis behandelt, indem er seinen Zustand ändert (einen neuen Zustand zurücksendend, der das vorherige Array ist, aber sortiert). Unabhängig davon, wie dies geschieht, führt dies zu einem Problem: Jede Komponente, die den Artikelreduzierer abonniert hat, erhält immer eine sortierte Liste. Ist das was du willst? Vielleicht ist die "sortierte" Anzeige ein Teil des Status der ui-Komponente und ist daher spezifisch für diese Komponente ....

  2. Lassen Sie den Reduzierer das unsortierte Array behalten und haben Sie zwei verschiedene Komponenten (oder eine Komponente mit einer zusätzlichen Stütze, die angibt, ob sie "sortiert" ist) und während der Renderfunktionen dieser Komponente entweder sortieren oder nicht sortieren , entsprechend der durch den Komponentenbehälter gegebenen Stütze. Dies geschieht technisch, indem die Containerkomponente einen Status (sortiert oder nicht sortiert) erhält, der als Prop an die Ansichtskomponente übergeben wird.

Wenn Sie neu reagieren/Redux und was ich sagte, macht wenig Sinn, zu dir, ich habe nichts dagegen Code hinzufügen - aber ich glaube, Ihre Frage über das Prinzip und nicht über den eigentlichen Code.

Verwandte Themen