React-Redux 中的 actionCreator、props 和组件是如何连接的? [英] How does the actionCreator, props, and component connect in React-Redux?

查看:37
本文介绍了React-Redux 中的 actionCreator、props 和组件是如何连接的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个代码:

import React, { Component } from 'react';从'react-redux'导入{连接};//这是一个连接属性import { selectBook } from '../actions/index';从redux"导入 { bindActionCreators };类 BookList 扩展组件 {渲染列表(){返回 this.props.books.map(book => {返回 (<li key={book.title} className="list-group-item">{book.title} </li>);});}使成为() {返回 (<ul className="list-group col-sm-4">{this.renderList()})}}函数 mapStateToProps(state) {返回 {书籍:state.books}}函数 mapDispatchToProps(dispatch) {//无论何时调用 selectBook,结果都应该传递给所有的 reducer.//selectBook 值是一个 actionCreator,一个函数.return bindActionCreators({ selectBook: selectBook }, dispatch)}导出默认连接(mapStateToProps,mapDispatchToProps)(BookList)

导出函数 selectBook(book) {console.log("已找到一本书:", book.title)}

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

connect(mapStateToProps, mapDispatchToProps)(BookList)

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

这个函数是做什么的:

function mapDispatchToProps(dispatch) {//无论何时调用 selectBook,结果都应该传递给所有的 reducer.//selectBook 值是一个 actionCreator,一个函数.return bindActionCreators({ selectBook: selectBook }, dispatch)}

这些是内置在 redux 函数中的吗?他们返回什么?到底是怎么回事?什么是dispatch?

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

如何在 BookList 组件中提供 props?

解决方案

你的问题太多了,我们试图解释它的努力可能会让你更加困惑.我强烈建议您观看 Redux 创建者的这两个视频:

Redux 入门惯用的 Redux

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

此外,Redux 的官方文档 很棒,如果您将其与视频一起使用,将非常适合你的学习.

但是,不管怎样,让我回答你的问题.

第一个问题

<块引用>

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

connect(mapStateToProps, mapDispatchToProps)(BookList)

<块引用>

这是怎么回事?这部分是否负责使状态和组件 BookList 可用的 dispatch 方法?

回答

connect 这里是由 react-redux 包提供的,而不是 redux 本身.它是一个辅助高阶函数,用于向组件打开状态和动作创建器.所以,你猜对了.这就是人们通常将他们的组件连接到商店以获取状态和分派(以使用动作创建者)的方式.

第二个问题

function mapDispatchToProps(dispatch) {//无论何时调用 selectBook,结果都应该传递给所有的 reducer.//selectBook 值是一个 actionCreator,一个函数.return bindActionCreators({ selectBook: selectBook }, dispatch)}

<块引用>

这些是内置在 redux 函数中的吗?他们返回什么?什么是继续?什么是派遣?

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

道具如何在组件 BookList 中可用?

回答

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

mapDispatchToProps 将您的动作创建器函数作为道具打开给您的组件.有几种方法可以使用它,bindActionCreators 是其中之一,但实际上您在这里不需要它.如果您在将动作创建者分派或传递给不知道 Redux 的子组件时需要它,则可以获取状态.所以,bindActionCreators 并不是理解 mapDispatchToProps 的好开始.

基本上是这样的:

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

在这里,您将向组件打开 someFunction() 动作创建器,名称为 someFunction.您可以使用不同的名称,也可以在这里做其他人员,然后根据此dispatch您的动作创建者.但是在这个例子中,你没有做任何额外的事情,只是调度动作创建者.所以,这里有一个简写:

const mapDispatchToProps = {一些功能,}

是的,对于这种情况,这会做同样的事情.甚至,还有一个更短的:

connect(mapStateToProps, {someFunction})(Component)

不使用 mapDispatchToProps 你可以像这样使用你的动作创建器,然后在你的组件中作为道具.

此外(是的,还有更多:))在连接中不使用任何函数参数的事件,我们可以使用动作创建者.

connect()(组件)连接(mapStateToProps)(组件)

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

this.props.dispatch(someFunction())

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

你可以这样写mapDispatchToProps:

const mapDispatchToProps = dispatch =>( {选择书:书 =>调度(选择书(书)),});

在这里,您在组件中使用 selectBook 作为 this.props.selectBook 并分派一个动作.你实际上看到你的道具触发了一个函数,它在这里调度你的真实动作创建者.请记住,动作创建者返回对象,这些对象需要被分派才能通过 reducer.因此,您正在调度您的操作创建者(由 selectBook 返回.

现在,使用 bindActionCreators 而不使用它的真正优势,您可以将其编写为:

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

或者使用 ES6 中具有相同名称的对象键的一些简写:

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

这比第一个略短.你不需要指向一个函数并调度它.您将动作创建者交给 bindActionCreators,它会为您完成工作.

现在,由于您只是在调度,因此较短:

const mapDispatchToProps = {选择书,};

即使没有mapDispatchToProps:

connect( mapStateToProps, { selectBook } )( BookList )

所以,Providerconnectreact-redux 提供,让我们的生活更轻松.mapStateToPropsmapDispatchToPropsconnect 等待的函数.名称并不重要,我们可以为它们使用任何名称,但这些是每个人都使用的事实上的名称.顺序很重要,如果我们想跳过 mapStateToProps,我们必须在它的位置使用 null,例如:

connect( null, mapDispatchToProps )( 组件 )

没有 connect 实际上我们可以使用 store 和它包含的内容 getState, dispatch, subscribe 在任何组件中有两种方式:

  • 不要使用 react-redux 并将 store 作为 prop 一直传递到您要使用的每个组件.然后通过 this.props.store 访问它.
  • 使用react-reduxProvider,然后使用context为组件获取store.

正如您所想象的那样,将 store 一直传递到组件是一场噩梦.

要使用 storecontext 首先你需要指定组件的 contextTypes:

BookList.contextTypes = {商店:React.PropTypes.object.isRequired};

之后你可以从 this.context.store 获取 store 并使用 getState 获取状态或 dispatch 来调度你的动作创作者.

如果我们不使用connect,我们的组件会是什么样子:

import React, { Component } from "react";import { selectBook } from "../actions/index";类 BookList 扩展组件 {渲染列表(){返回 this.context.store.getState().books.map( book =>( <li键={书名}onClick={() =>this.context.store.dispatch( selectBook( book ))}>{书名}) );}使成为() {返回 (<ul>{this.renderList()});}}BookList.contextTypes = {商店:React.PropTypes.object.isRequired,};导出默认书单;

这里我们使用:this.context.store.getState().books 而不是 this.props.booksthis.context.store.dispatch( selectBook( book )) 而不是 this.props.selectBook( book ).如您所见,我们可以通过这种方式到达状态并调度我们的动作创建者.但是通过 connect 及其灵活性,我们可以以一种简洁明了的方式打开我们的状态和动作创建器.

I have this code:

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

The parts that I don't understand are this:

connect(mapStateToProps, mapDispatchToProps)(BookList)

What is going on? Is this part responsible for making the state and the dispatch method available to the component BookList?

What is this function doing:

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

Are these built in redux functions? What are they returning? What is going on? What is dispatch?

The value selectBook on the right side is a function right? So I guess it gets called, and the return value will flow through the reducers via the dispatch method? But then what is bindActionCreators doing?

How are props made available inside the component BookList?

解决方案

You have too many questions and how hard we try to explain it what is going on here probably confuses you more. I strongly advise you to watch those two videos from the creator of Redux:

Getting started with Redux and Idiomatic Redux

Those vidoes explain what is Redux, how does its pieces get together. So, before following any other tutorials first grasp Redux itself.

Also, Redux's official documentation is great, if you follow it alongside with the videos would be great for your study.

But, let me answer your questions anyway.

First question

The parts that I don't understand are this:

connect(mapStateToProps, mapDispatchToProps)(BookList)

What is going on? Is this part responsible for making the state and the dispatch method available to the component BookList?

Answer

connect here is provided by react-redux package, not redux itself. It is a helper higher order function used to open your state and action creators to your components. So, you guessed right. This is how people generally connect their components into the store to get state and dispatch (to use action creators).

Second question

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

Are these built in redux functions? What are they returning? What is going on? What is dispatch?

The value selectBook on the right side is a function right? So I guess it gets called, and the return value will flow through the reducers via the dispatch method? But then what is bindActionCreators doing?

How are props made available inside the component BookList?

Answer

No, they are not built in Redux functions as I explained in the first answer. mapStateToProps opens your state to your component and feed it as props. So, if you open any state to your component with connect and mapStateToProps you get this state as props. In your example you get the books state from your global state and open this as books to your component. Then this component gets this as this.props.books.

mapDispatchToProps opens your action creator functions to your component as props. There a couple of ways using this, bindActionCreators is one of them but actually you don't need it here. It is good for getting state if you need it while you are dispatching or passing your action creators to a child component which does not aware of Redux. So, bindActionCreators is not a good start to understand mapDispatchToProps.

Basically it is like that:

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

Here you are opening your someFunction() action creator to your component as the name someFunction. You can use a different name or you can do other staff here and then dispatch your action creator according to this. But in this example you are not doing anything extra, just dispatching the action creator. So, there is a shorthand for this:

const mapDispatchToProps = {
    someFunction,
}

Yes, for this situation this does the same thing. Even, there is a shorter one:

connect(mapStateToProps, {someFunction})(Component)

Without using a mapDispatchToProps you can use your action creators like this, then get as props in your components.

Also (yes there is more :)) event without using any function argument in connect, we can use action creators.

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

If we skip mapDispatchToProps like one of the methods above, dispatch is automatically passed to the component props. Then, we can use it like any other prop to dispatch our action creator:

this.props.dispatch(someFunction())

For your example it goes like this (I know this app, so I'm using real action creator example here).

You can write mapDispatchToProps like this:

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

Here you use selectBook as this.props.selectBook in your component and dispatch an action. You see actually your prop fires a function and it dispatches your real action creator here. Remember, action creators returns objects and those objects need to be dispatched in order to go through reducers. So, you are dispatching your action creator (which is returned by selectBook.

Now, with bindActionCreators without using its real advantages you can write it as:

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

or with some ES6 shorthand for object keys which has the same name:

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

This is slightly shorter than the first one. You don't need to point a function and dispatch it. You gave the action creator to bindActionCreators and it does the job for you.

Now, the shorter one since you are just dispatching:

const mapDispatchToProps = {
  selectBook,
};

Even without mapDispatchToProps:

connect( mapStateToProps, { selectBook } )( BookList )

So, Provider, connect are being provided by react-redux to make the life easier for us. mapStateToProps and mapDispatchToProps are the functions which connect waits. Names are not important, we can use any name for them but these are the defacto ones everyone uses. The order is important and if we want to skip mapStateToProps we must use null in its place like:

connect( null, mapDispatchToProps )( Component )

Without connect actually we can use store and what it contains getState, dispatch, subscribe in any component with two ways:

  • Don't use react-redux and pass the store as prop all the way down to each component you want to use. Then reach it via this.props.store.
  • Use react-redux's Provider, then use context for the component to get the store.

As you can imagine passing the store all the way down to components is a nightmare.

To use store with context first you need to specify the contextTypes of the component:

BookList.contextTypes = {
  store: React.PropTypes.object.isRequired
};

After doing that you can grab store from this.context.store and use getState to get the state or dispatch to dispatch your action creators.

Here how our component would be if we didn't use 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;

Here we use: this.context.store.getState().books instead of this.props.books and this.context.store.dispatch( selectBook( book )) instead of this.props.selectBook( book ). As you can see we can reach state and can dispatch our action creators with this way. But with connect and its flexibility we open our state and action creators in a nice and clean way.

这篇关于React-Redux 中的 actionCreator、props 和组件是如何连接的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆