actionCreator,道具和组件在React-Redux中如何连接?

时间:2018-07-22 00:10:34

标签: reactjs redux react-redux

我有此代码:

$str = '<p>2:45 text goes here</p>
<p>43:41 - text goes here</p>';
$str = preg_replace('/<p>(\d+:\d+ ((?!<\/p>).)+)<\/p>/','<li>$1</li>',$str);
echo $str;

import React, { Component } from 'react';
import { connect } from 'react-redux'; //this is a single connect property
import { selectBook } from '../actions/index';
import { bindActionCreators } from 'redux';

class BookList extends Component {
  renderList() {
    return this.props.books.map(book => {
      return (
        <li key={book.title} className="list-group-item"> {book.title} </li>
      );
    });
  }

  render() {
    return (
      <ul className="list-group col-sm-4">
        {this.renderList()}
      </ul>
    )
  }
}

function mapStateToProps(state) {
  return {
    books: state.books
  }
}

function mapDispatchToProps(dispatch) {
  // Whenver selectBook is called, the result should be passed to all of the reducers.
  // selectBook value is an actionCreator, a function.
  return bindActionCreators({ selectBook: selectBook }, dispatch)
}

export default connect(mapStateToProps, mapDispatchToProps)(BookList)

我不理解的部分是这样:

export function selectBook(book) {
  console.log("A book has been seelcted:", book.title)
}

这是怎么回事?这部分负责将状态和调度方法提供给组件connect(mapStateToProps, mapDispatchToProps)(BookList) 吗?

此函数在做什么:

BookList

这些内置的redux函数吗?他们还回来什么?到底是怎么回事?什么是function mapDispatchToProps(dispatch) { // Whenver selectBook is called, the result should be passed to all of the reducers. // selectBook value is an actionCreator, a function. return bindActionCreators({ selectBook: selectBook }, dispatch) }

右边的值dispatch是函数对吗?所以我猜想它会被调用,并且返回值将通过调度方法流经reducers?但是selectBook在做什么呢?

如何在组件bindActionCreators中提供道具?

1 个答案:

答案 0 :(得分:3)

您有太多问题,我们尝试解释这一问题的努力可能会使您更加困惑。我强烈建议您观看Redux创作者的这两段视频:

Getting started with ReduxIdiomatic Redux

那些视频解释了什么是Redux,它的各个部分如何融合在一起。因此,在进行任何其他教程之前,请先掌握Redux本身。

此外,Redux的official documentation很棒,如果您将其与视频一起观看,将对您的学习很有帮助。

但是,无论如何,让我回答您的问题。

第一个问题

  

我不理解的部分是这样:

connect(mapStateToProps, mapDispatchToProps)(BookList)
  

这是怎么回事?这部分负责建立国家和   组件BookList可用的调度方法?

答案

connectreact-redux包提供的,而不是redux本身提供的。它是一个辅助的高阶函数,用于向您的组件打开状态和动作创建者。所以,你猜对了。人们通常是通过这种方式将其组件连接到商店以获取状态和调度(以使用动作创建者)。

第二个问题

function mapDispatchToProps(dispatch) {
  // Whenver selectBook is called, the result should be passed to all of the reducers.
  // selectBook value is an actionCreator, a function.
  return bindActionCreators({ selectBook: selectBook }, dispatch)
}
  

这些内置的redux函数吗?他们还回来什么?什么是   继续吗什么是调度?

     

右边的selectBook值是函数吧?所以我猜   它被调用,返回值将流经reducers   通过调度方法?但是,bindActionCreators在做什么呢?

     

如何在组件BookList中提供道具?

答案

不,正如我在第一个答案中所解释的那样,它们不是Redux函数内置的。 mapStateToProps将您的状态打开到组件中,并将其作为道具提供。因此,如果您使用connectmapStateToProps打开组件的任何状态,则此状态将作为props。在您的示例中,您从全局状态中获得了books状态,并以books的形式打开了您的组件。然后,此组件将其作为this.props.books

mapDispatchToProps将您的动作创建者功能作为道具打开。有两种使用方法,bindActionCreators是其中一种,但实际上您在这里不需要它。如果在调度动作创建者或将动作创建者传递给不了解Redux的子组件时需要它,则对于获得状态非常有用。因此,bindActionCreators并不是了解mapDispatchToProps的一个好的开始。

基本上就是这样:

const mapDispatchToProps = dispatch => ({
  someFunction: () => dispatch(someFunction())
})

在这里,您将someFunction()动作创建者以someFunction的名称打开到组件中。您可以使用其他名称,也可以在此处使用其他人员,然后根据此dispatch来创建动作创建者。但是在此示例中,您没有做任何额外的事情,只是调度了动作创建者。因此,这是一个简写:

const mapDispatchToProps = {
    someFunction,
}

是的,在这种情况下,它做同样的事情。甚至更短一些:

connect(mapStateToProps, {someFunction})(Component)

无需使用mapDispatchToProps,就可以像这样使用动作创建者,然后将其作为道具。

此外(是的,还有更多:))事件,而无需在connect中使用任何函数参数,我们可以使用动作创建器。

connect()(Component)
connect(mapStateToProps)(Component)

如果像上述方法之一一样跳过mapDispatchToProps,则dispatch将自动传递给组件props。然后,我们可以像使用其他任何道具一样使用它来分发我们的动作创建者:

this.props.dispatch(someFunction())

对于您的示例,它是这样的(我知道这个应用程序,所以我在这里使用真实动作创建者示例)。

您可以这样写mapDispatchToProps

const mapDispatchToProps = dispatch => ( {
  selectBook: book => dispatch( selectBook( book ) ),
} );

在这里,您将selectBook用作组件中的this.props.selectBook并调度操作。您会看到您的道具实际上触发了一个函数,并在此处调度了您的实际动作创建者。请记住,动作创建者返回对象,并且需要分派这些对象才能通过化简器。因此,您正在分派动作创建者(由selectBook返回。

现在,bindActionCreators可以利用它的真正优势,将其编写为:

const mapDispatchToProps = dispatch => (
    bindActionCreators( { selectBook: selectBook }, dispatch )
);

或某些具有相同名称的对象键的ES6速记:

const mapDispatchToProps = dispatch => (
    bindActionCreators( { selectBook }, dispatch )
);

这比第一个短。您无需指向函数并分派它。您将动作创建者交给了bindActionCreators,它就为您完成了工作。

现在,距离较短的那是因为您刚刚调度:

const mapDispatchToProps = {
  selectBook,
};

即使没有mapDispatchToProps

connect( mapStateToProps, { selectBook } )( BookList )

因此,Provider提供了connectreact-redux,使我们的生活更轻松。 mapStateToPropsmapDispatchToPropsconnect等待的功能。名称并不重要,我们可以为它们使用任何名称,但这是每个人都使用的事实上的名称。该顺序很重要,如果要跳过mapStateToProps,必须在其位置使用null,例如:

connect( null, mapDispatchToProps )( Component )

实际上,没有connect,我们可以通过两种方式使用store及其包含的内容getStatedispatchsubscribe,包括两种方式:

  • 不要使用react-redux并将store作为道具一直传递到要使用的每个组件。然后通过this.props.store到达它。
  • 使用react-redux的{​​{1}},然后对组件使用Provider以获取context

您可以想象,将商店一直传递到各个组件是一场噩梦。

首先将storestore一起使用,您需要指定组件的context

contextTypes

这样做之后,您可以从BookList.contextTypes = { store: React.PropTypes.object.isRequired }; 获取存储,并使用this.context.store来获取状态,或者使用getState来分发动作创建者。

如果不使用dispatch,我们的组件将是这样:

connect

这里我们使用:import React, { Component } from "react"; import { selectBook } from "../actions/index"; class BookList extends Component { renderList() { return this.context.store.getState().books.map( book => ( <li key={book.title} onClick={() => this.context.store.dispatch( selectBook( book ))} > {book.title} </li> ) ); } render() { return ( <ul> {this.renderList()} </ul> ); } } BookList.contextTypes = { store: React.PropTypes.object.isRequired, }; export default BookList; 代替this.context.store.getState().booksthis.props.books代替this.context.store.dispatch( selectBook( book ))。如您所见,我们可以达到状态,并可以通过这种方式派遣我们的行动创建者。但是,借助this.props.selectBook( book )及其灵活性,我们可以以一种简洁的方式打开状态和动作创建者。