什么是mapDispatchToProps?

时间:2016-09-09 20:26:43

标签: reactjs redux

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

  

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

这实际上没有任何意义。当您已经mapDispatchToProps时,为什么需要mapStateToProps

他们还提供了这个方便的代码示例:

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

有人可以用非专业人士的术语解释这个功能是什么以及为什么它有用吗?

6 个答案:

答案 0 :(得分:508)

我觉得没有一个答案已经明确为什么mapDispatchToProps有用。

这实际上只能在container-component模式的上下文中回答,我在第一次阅读时发现了最好的理解:

https://medium.com/@learnreact/container-components-c0e67432e005#.1a9j3w1jl

然后

http://redux.js.org/docs/basics/UsageWithReact.html

简而言之,您的components应该只关注显示内容。 他们应该从中获取信息的唯一地方是他们的道具

与"分开显示内容" (组件)是:

  • 你如何展示这些东西,
  • 以及您如何处理事件。

这就是containers的用途。

因此,设计精良"模式中的component看起来像这样:

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商店)显示的信息,并且还从其道具sendTheAlert()获取其动作功能。

mapDispatchToProps进来的地方:相应的container

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

我想知道你是否可以看到,现在它是container [1] 知道有关redux和dispatch以及存储,状态和......的东西。< / p>

模式中的componentFancyAlerter,渲染不需要知道任何内容:它的方法是在onClick处调用按钮,通过它的道具。

并且...... mapDispatchToProps是redux提供的有用方法,让容器可以轻松地将该函数传递到其道具上的包装组件中。

所有这些看起来都非常像文档中的todo示例,而另一个答案在这里,但我试图根据模式来强制为什么

(注意:由于您无法访问mapStateToPropsmapDispatchToProps的基本原因,您无法将dispatch用于与mapStateToProp相同的目的1}}。因此,您无法使用mapStateToProps为包装组件提供使用dispatch的方法。

我不知道为什么他们选择将它分成两个映射函数 - 让mapToProps(state, dispatch, props) IE一个函数同时执行这两个函数可能更整洁!

[1]请注意,我故意明确命名容器FancyButtonContainer,以强调它是一个&#34;&#34; - 容器的身份(因此存在!)作为&#34;事物&#34;有时会在速记中丢失

export default connect(...)

大多数示例中显示的

语法

答案 1 :(得分:65)

这基本上是一种速记。所以不必写:

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

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

this.props.onTodoClick(id);

或更有可能在这种情况下,您将其作为事件处理程序:

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

Dan Abramov在这里有一段有用的视频:https://egghead.io/lessons/javascript-redux-generating-containers-with-connect-from-react-redux-visibletodolist

答案 2 :(得分:45)

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

答案 3 :(得分:16)

来自mapStateToProps库的

mapDispatchToPropsconnectreact-redux提供了一种便捷的方式来访问您商店的statedispatch功能。因此,基本上连接是一个更高阶的组件,如果这对你有意义,你也可以作为包装器。因此,每次更改state mapStateToProps时,都会使用新的state调用props,随后mapDispatchToProps更新组件将运行渲染功能,以便在浏览器中呈现您的组件。 props还会在组件的state上存储键值,通常它们采用函数的形式。通过这种方式,您可以从您的组件onClickonChange事件中触发const TodoListComponent = ({ todos, onTodoClick }) => ( <ul> {todos.map(todo => <Todo key={todo.id} {...todo} onClick={() => onTodoClick(todo.id)} /> )} </ul> ) const mapStateToProps = (state) => { return { todos: getVisibleTodos(state.todos, state.visibilityFilter) } } const mapDispatchToProps = (dispatch) => { return { onTodoClick: (id) => { dispatch(toggleTodo(id)) } } } function toggleTodo(index) { return { type: TOGGLE_TODO, index } } const TodoList = connect( mapStateToProps, mapDispatchToProps )(TodoList) 更改。

来自docs:

console.log("lang = " + document.documentElement.lang);

另外,请确保您熟悉React stateless functionsHigher-Order Components

答案 4 :(得分:1)

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

mapDispatchToProps收到dispatchprops,用于绑定操作创建者以进行调度,因此当您执行生成的函数时,操作将被调度。

我发现这只会让您免于在组件中执行dispatch(actionCreator()),从而使其更容易阅读。

https://github.com/reactjs/react-redux/blob/master/docs/api.md#arguments

答案 5 :(得分:1)

现在假设有一个针对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(),将dispatch动作映射到props(我们组件的props)

因此,道具onTodoClickmapDispatchToProps函数的键,该函数委托进一步派遣行动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())
      }
    }
}