2016-08-25 3 views
1

私はReduxとReactを初めて使用しています。私は反応コンポーネントのソートを実装しようとしていますが、私が知っている限り、Reduxのpropsを操作することはできません。私はそれがでdumpコンポーネントだと思うArticleListコンポーネントにReduxの-反応することを渡すarticles私が手にしたらここに私のコンポーネント子どもの反応の中で小道具を操作するための冗長反応の方法は何ですか?

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); 

年代に

をReduxの反応することを行うための正しい方法は何ですか

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> 
    ); 
    } 
} 

このコンポーネントでは、ユーザーが列をクリックしてその列で表全体を並べ替えることができる並べ替え機能が必要です。

articlesオブジェクトの例は、これReduxのフローは、コンポーネントが減速状態を更新する、それによってリッスンするアクションを呼び出すある

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

どの属性に基づいてソートしますか?アーティクルがオブジェクトであるため、 'this.props.articles.sort()'は機能しません。 –

+0

申し訳ありません。例として、1つの属性でソートしたいと思います。質問を更新します。 – toy

答えて

1

あろう。その状態をリッスンするコンテナ(接続関数でラップされたコンポーネント)は、新しい状態で自身を再レンダリングします。

ここでは、親コンポーネント、ファンクションを起動するArticleListコンポーネント(ダムコンポーネント)、ArticleListApp(コンテナ、またはスマートコンポーネント)の列のonClickイベントをリッスンするリスナーがあります。 )。その結果、コンテナーがアクションを起こします。たとえば、props.sortByColumn( 'AUTHOR'、 'asc')と言います。このアクションは、あなたの行動のファイルで定義する必要があり、基本的にこの

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

リデューサーは、そのアクションを聞いされ、基本的に新しい順に表示される記事でお店を更新するようになります。

この更新が行われると、その状態をリスニングしているコンテナは、新しい状態で自身を再描画します。並べ替えたい列を持つ親を呼び出すすべての列にクリックハンドラーを配置できます。

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); 

そして、あなたの他のダムのコンポーネントは次のようになります:

あなたのコンポーネントは次のようになります

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

私が正しく理解していれば、これについて移動する2つの方法があります。

  1. ユーザーの操作に応じて、記事をレデューサーに保存したり、ソートしたり、ソートしたりしないでください。技術的には、これは、「ソート」アクションが(コンテナによって)起動され、その状態を変更することによってそのイベントを処理する減速器(前の配列であるがソートされた新しい状態を返す)によって行われます。これがどのように行われるかに関わらず、これは問題を引き起こします。記事減速機に登録されたコンポーネントは、常にソートされたリストを取得します。これは、あなたの望むことですか?たぶん「ソート」されたディスプレイは、UIコンポーネントの状態の一部であり、そのコンポーネントに固有のものです。

  2. レデューサーにソートされていない配列を保持させ、2つの異なるコンポーネント(またはソートされているかどうかを示す追加のプロンプトを持つコンポーネント)と、このコンポーネントのレンダリング機能の間にソートまたはソートしない、コンポーネントコンテナによって与えられた小道具に従って。技術的には、これは、コンテナコンポーネントに、ビューコンポーネントに小道具として渡される状態(ソートされたものかソートされていないもの)を持たせることによって行われます。

あなたが/ Reduxのと私が言ったあなたに意味をなさないを反応させるのに慣れていない場合、私は、コードを追加する気にしない - しかし、私はあなたの質問は、実際のコードについての原則とない程度だと思います。

関連する問題