我正在阅读Redux库的文档,它有这样的例子:

除了读取状态外,容器组件还可以分派动作。以类似的方式,您可以定义一个名为mapDispatchToProps()的函数,该函数接收dispatch()方法并返回您希望注入到表示组件中的回调道具。

这实际上毫无意义。为什么你需要mapDispatchToProps当你已经有mapStateToProps?

它们还提供了以下方便的代码示例:

const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(id))
    }
  }
}

这个函数是什么?为什么它有用?


当前回答

现在假设有一个redux动作为:

export function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}

当你导入它时,

import {addTodo} from './actions';

class Greeting extends React.Component {

    handleOnClick = () => {
        this.props.onTodoClick(); // This prop acts as key to callback prop for mapDispatchToProps
    }

    render() {
        return <button onClick={this.handleOnClick}>Hello Redux</button>;
    }
}

const mapDispatchToProps = dispatch => {
    return {
      onTodoClick: () => { // handles onTodoClick prop's call here
        dispatch(addTodo())
      }
    }
}

export default connect(
    null,
    mapDispatchToProps
)(Greeting);

正如函数名所说的mapDispatchToProps(),将调度动作映射到道具(我们组件的道具)

所以prop onTodoClick是mapDispatchToProps函数的一个键,它进一步委托调度addTodo动作。

此外,如果你想精简代码,绕过手动实现,那么你可以这样做,

import {addTodo} from './actions';
class Greeting extends React.Component {

    handleOnClick = () => {
        this.props.addTodo();
    }

    render() {
        return <button onClick={this.handleOnClick}>Hello Redux</button>;
    }
}

export default connect(
    null,
    {addTodo}
)(Greeting);

这就意味着

const mapDispatchToProps = dispatch => {
    return {
      addTodo: () => { 
        dispatch(addTodo())
      }
    }
}

其他回答

mapStateToProps接收状态和道具,并允许您从状态中提取道具以传递给组件。

mapDispatchToProps接收分派和道具,用于将动作创建者绑定到分派,以便在执行结果函数时分派动作。

我发现这只会让你不必在你的组件中做dispatch(actionCreator()),从而使它更容易阅读。

React redux: connect:参数

它基本上是一种速记。所以不用写:

this.props.dispatch(toggleTodo(id));

您将使用mapDispatchToProps,如示例代码所示,然后在其他地方编写:

this.props.onTodoClick(id);

或者在这种情况下,你会把它作为事件处理程序:

<MyComponent onClick={this.props.onTodoClick} />

这里有一段丹·阿布拉莫夫的视频: Redux:使用connect()生成容器

mapStateToProps()是一个实用工具,它帮助你的组件获得更新的状态(由其他一些组件更新), mapDispatchToProps()是一个实用工具,它将帮助组件触发一个操作事件(调度可能导致应用程序状态更改的操作)

我觉得没有一个答案能明确说明为什么mapDispatchToProps是有用的。

这个问题只能在容器组件模式的上下文中回答,我发现最好的理解方式是先阅读《容器组件然后使用React》。

简而言之,你的组件应该只关心显示内容。他们唯一能得到信息的地方就是他们的道具。

与“显示内容”(组件)分开的是:

你如何把东西展示出来, 以及你如何处理事件。

这就是容器的作用。

因此,模式中“设计良好”的组件看起来是这样的:

class FancyAlerter extends Component {
    sendAlert = () => {
        this.props.sendTheAlert()
    }

    render() {
        <div>
          <h1>Today's Fancy Alert is {this.props.fancyInfo}</h1>
          <Button onClick={sendAlert}/>
        </div>
     }
}

看看这个组件如何从props(通过mapStateToProps来自redux存储)中获得它所显示的信息,它还从它的props中获得它的动作函数:sendTheAlert()。

这就是mapDispatchToProps的用武之地:在相应的容器中

// FancyButtonContainer.js

function mapDispatchToProps(dispatch) {
    return({
        sendTheAlert: () => {dispatch(ALERT_ACTION)}
    })
}

function mapStateToProps(state) {
    return({fancyInfo: "Fancy this:" + state.currentFunnyString})
}

export const FancyButtonContainer = connect(
    mapStateToProps, mapDispatchToProps)(
    FancyAlerter
)

我想知道你是否能看到,现在它是容器1,它知道redux,调度,存储,状态和…的东西。

该模式中的组件FancyAlerter,它进行渲染,不需要知道任何这些东西:它通过它的props在按钮的onClick处调用它的方法。

和…mapDispatchToProps是redux提供的一种有用的方法,可以让容器轻松地将该函数传递到其props上的包装组件中。

所有这些看起来都很像文档中的todo示例,这里还有另一个答案,但我试图把它放在模式的光照下,以强调原因。

(注意:你不能将mapStateToProps用于与mapDispatchToProps相同的目的,其基本原因是你不能访问mapStateToProp内部的调度。因此,您不能使用mapStateToProps为包装组件提供使用分派的方法。

我不知道为什么他们选择把它分成两个映射函数-它可能会更整洁的mapToProps(状态,调度,道具)IE一个函数来做这两件事!


1注意,我故意显式地将容器命名为FancyButtonContainer,以突出它是一个“东西”——容器作为“东西”的身份(因此存在!)有时会在简写中丢失

导出默认连接(…) ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

大多数示例中显示的语法

现在假设有一个redux动作为:

export function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}

当你导入它时,

import {addTodo} from './actions';

class Greeting extends React.Component {

    handleOnClick = () => {
        this.props.onTodoClick(); // This prop acts as key to callback prop for mapDispatchToProps
    }

    render() {
        return <button onClick={this.handleOnClick}>Hello Redux</button>;
    }
}

const mapDispatchToProps = dispatch => {
    return {
      onTodoClick: () => { // handles onTodoClick prop's call here
        dispatch(addTodo())
      }
    }
}

export default connect(
    null,
    mapDispatchToProps
)(Greeting);

正如函数名所说的mapDispatchToProps(),将调度动作映射到道具(我们组件的道具)

所以prop onTodoClick是mapDispatchToProps函数的一个键,它进一步委托调度addTodo动作。

此外,如果你想精简代码,绕过手动实现,那么你可以这样做,

import {addTodo} from './actions';
class Greeting extends React.Component {

    handleOnClick = () => {
        this.props.addTodo();
    }

    render() {
        return <button onClick={this.handleOnClick}>Hello Redux</button>;
    }
}

export default connect(
    null,
    {addTodo}
)(Greeting);

这就意味着

const mapDispatchToProps = dispatch => {
    return {
      addTodo: () => { 
        dispatch(addTodo())
      }
    }
}