繁体   English   中英

在子代组件中操纵道具的redux-react方法是什么

[英]What's the redux-react way to manipulate props in react children component

我是Redux和React的新手。 我正在尝试为React组件实现排序,但据我所知,您不允许在Redux中操作props 在redux-react中这样做的正确方法是什么

这是我的组成部分

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

获得articles ,将其传递给ArticleList组件,我认为它是redux-react中的dump组件

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对象的示例是

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

因此Redux流是组件将调用reducer侦听的操作,从而更新状态。 侦听该状态的任何容器(包装在connect函数中的组件)都将使用新状态重新呈现自己。

因此,您要在此处做的事情是有一个侦听器,该侦听器侦听ArticleList组件(哑组件)中列的onClick事件,该事件向父组件ArticleListApp(容器或智能组件)触发一个函数。 例如,这将导致容器触发一个动作,例如props.sortByColumn('AUTHOR','asc')。 该动作应该在您的动作文件中定义,基本上是这样的

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

Reducer将监听该操作,并且基本上将使用要在新订单中列出的商品来更新您的商店。

当该更新发生时,侦听该状态的容器将使用新状态重新呈现自己。 您可以将单击处理程序放在您要调用父级的每一列上,并将其作为排序依据。

您的组件将如下所示:

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. 物品应根据用户的交互作用保存在减速器中,分类还是不分类。 从技术上讲,这是通过(容器)触发“排序”操作,然后通过更改事件的状态(返回一个新的状态,该状态是先前的数组但已排序)的化简处理该事件来完成的。 无论如何完成,这都会带来一个问题:订阅商品减速器的任何组件都将始终获得排序列表。 这是你想要的吗? 也许“排序”显示是ui组件状态的一部分,并且特定于该组件,所以...

  2. 让减速器保留未排序的数组并具有两个不同的组件(或一个带有附加道具的组件,说明其是否“已排序”),并且在该组件的渲染功能期间,根据道具进行排序或不排序由components容器给出。 从技术上讲,这是通过使容器组件具有作为道具传递给视图组件的状态(已排序或未排序)来完成的。

如果您不熟悉React / redux,而我所说的话对您来说意义不大,那么我不介意添加代码-但我认为您的问题是关于原理而不是实际代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM