你有太多的问题,而我们如何努力解释这里发生的事情可能会让你更加困惑。我强烈建议您观看 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
并通过store
as 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
及其灵活性,我们以一种良好而干净的方式开放我们的状态和动作创建者。