React-Redux 中的 actionCreator、props 和组件如何连接?

2024-01-29

我有这个代码:

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)

and

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

我不明白的部分是这样的:

connect(mapStateToProps, mapDispatchToProps)(BookList)

到底是怎么回事?该部分负责使状态和调度方法可供组件使用吗BookList?

这个函数在做什么:

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 函数吗?他们要返回什么?到底是怎么回事?什么是dispatch?

价值selectBook右边是一个函数吧?所以我猜它会被调用,并且返回值将通过调度方法流经减速器?但那么什么是bindActionCreators doing?

如何在组件内部提供 propsBookList?


你有太多的问题,而我们如何努力解释这里发生的事情可能会让你更加困惑。我强烈建议您观看 Redux 创建者的这两段视频:

Redux 入门 https://egghead.io/courses/getting-started-with-redux and 惯用的还原 https://egghead.io/courses/building-react-applications-with-idiomatic-redux

这些视频解释了什么是 Redux,它的各个部分如何组合在一起。因此,在学习任何其他教程之前,首先要掌握 Redux 本身。

另外,Redux 的官方文档 https://redux.js.org/太棒了,如果你跟着视频一起学习,对你的学习会有很大的帮助。

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

第一个问题

我不明白的部分是这样的:

connect(mapStateToProps, mapDispatchToProps)(BookList)

到底是怎么回事?这部分负责使状态和 组件 BookList 可用的调度方法?

Answer

connect这里是由提供的react-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 是一个函数,对吧?所以我猜 它被调用,返回值将流经减速器 通过调度方法?那么bindActionCreators 到底在做什么呢?

如何在组件 BookList 中使用 props?

Answer

不,正如我在第一个答案中解释的那样,它们不是内置于 Redux 函数中的。mapStateToProps将您的状态打开到您的组件并将其作为道具提供。因此,如果您使用以下命令打开组件的任何状态connect and mapStateToProps你得到这个状态作为道具。在你的例子中你得到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()(Component)
connect(mapStateToProps)(Component)

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

this.props.dispatch(someFunction())

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

你可以写mapDispatchToProps像这样:

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

这里你使用selectBook as 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 )

So, Provider, connect正在由以下人员提供react-redux让我们的生活更轻松。mapStateToProps and mapDispatchToProps是以下函数connect等待。名称并不重要,我们可以为它们使用任何名称,但这些是每个人都使用的事实上的名称。顺序很重要,如果我们想跳过mapStateToProps我们必须使用null在它的位置,如:

connect( null, mapDispatchToProps )( Component )

Without connect实际上我们可以使用store以及它包含什么getState, dispatch, subscribe在任何组件中都有两种方式:

  • 不要使用react-redux并通过storeas prop 一直到您想要使用的每个组件。然后通过到达它this.props.store.
  • Use react-redux's Provider,然后使用context为了让组件得到store.

正如您可以想象的那样,将存储一路传递到组件是一场噩梦。

To use store with 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().books代替this.props.books and this.context.store.dispatch( selectBook( book ))代替this.props.selectBook( book )。正如您所看到的,我们可以达到状态并可以通过这种方式派遣我们的动作创建者。但与connect及其灵活性,我们以一种良好而干净的方式开放我们的状态和动作创建者。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React-Redux 中的 actionCreator、props 和组件如何连接? 的相关文章

随机推荐