什么是mapDispatchToProps?

Cod*_*rer 329 reactjs redux

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

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

这实际上没有任何意义.dispatch()你已经拥有了为什么需要mapDispatchToProps

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

const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(id))
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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

Gre*_*ade 539

我觉得没有一个答案已经明确为什么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>
     }
}
Run Code Online (Sandbox Code Playgroud)

看看这个组件如何从props(它来自redux商店mapStateToProps)获取它显示的信息,它还从它的props获取其动作函数: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
)
Run Code Online (Sandbox Code Playgroud)

我想知道你是否可以看到,现在知道有关减少和调度以及存储,状态和......的东西container [1].

component图案中,FancyAlerter,这并呈现并不需要了解任何东西:它得到它的方法在调用onClick按钮,通过它的道具.

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

所有这些看起来都非常像文档中的todo示例,这里有另一个答案,但我试图根据模式来强制推理它.

(注意:您不能使用mapStateToPropsmapDispatchToProps您无法访问dispatch内部的基本原因相同的目的mapStateToProp.因此您不能使用mapStateToProps为包装组件提供使用的方法dispatch.

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


[1]请注意,我故意明确命名容器FancyButtonContainer,以突出它是一个"东西" - 容器的身份(因此存在!)作为"一件事"有时会在速记中丢失

export default connect(...)

大多数示例中显示的语法

  • @ user2130130没有.这是关于好的设计.如果你将你的组件耦合到store.dispatch,那么当你决定将redux分解出来,或者想要使用一些不是基于redxu的地方(或者我现在想不到的其他东西)时,你会被困在很多变化.您的问题概括为"我们为什么要打扰'优秀的设计实践' - 您可以获得相同的功能,但是您可以编写代码".提供了mapDispatchToProps,因此您可以编写设计良好,干净利用的分离组件. (7认同)
  • 我仍然想知道:通过直接从组件中调用store.dispatch无法处理所需的功能? (5认同)
  • 我真正没有得到的是:`ALERT_ACTION`是动作函数还是动作函数返回的`type`?:/太困惑了 (4认同)
  • 如果您有多个动作创建者需要作为道具传递给子组件,一种替代方法是在 mapDispatchToProps 中使用 bindActionCreators 将它们包装起来(参见 http://redux.js.org/docs/api/bindActionCreators.html);另一种选择是简单地为 connect() 提供一个动作创建者的对象,例如,connect(mapStateToProps, {actioncreators}),react-redux 将为您用 dispatch() 包装它们。 (2认同)

ham*_*stu 72

它基本上是一种速记.所以不必写:

this.props.dispatch(toggleTodo(id));
Run Code Online (Sandbox Code Playgroud)

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

this.props.onTodoClick(id);
Run Code Online (Sandbox Code Playgroud)

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

<MyComponent onClick={this.props.onTodoClick} />
Run Code Online (Sandbox Code Playgroud)

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

  • 如果您不提供自己的`mapDispatch`函数,Redux将使用默认值.默认的`mapDispatch`函数只需要`dispatch`函数引用,并将它作为`this.props.dispatch`提供给你. (14认同)
  • 调度方法由[Provider Component]传递(https://github.com/reactjs/react-redux/blob/master/docs/api.md#provider-store) (7认同)
  • 谢谢。我还想知道,调度首先是如何添加到道具中的? (2认同)

Sai*_*uri 51

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


Vla*_*mon 19

mapStateToProps,mapDispatchToPropsconnectreact-redux库提供了一种方便的方式来访问您的商店statedispatch功能.因此,基本上连接是一个更高阶的组件,如果这对你有意义,你也可以作为包装器.因此,每次state更改时mapStateToProps都将使用new调用,state随后props更新组件将运行渲染功能以在浏览器中呈现组件.mapDispatchToProps还存储组件的键值props,通常它们采用函数的形式.通过这种方式,您可以触发state组件onClick,onChange事件的更改.

来自docs:

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) 
Run Code Online (Sandbox Code Playgroud)

还要确保您熟悉React无状态函数高阶组件

  • 它可能与事件有关,**dispatch**只是一个**函数**而且是改变你的应用程序的唯一方法**状态**.**mapStateToProps**是将**商店**的**dispatch**函数暴露给React Component的一种方法.另请注意,connect不是**redux**的一部分,实际上它只是一个实用程序和样板文件减少库,名为**react-redux**,可与react和redux一起使用.如果您将**商店**从根反应组件传递给子项,则可以在没有**react-redux**的情况下获得相同的结果. (2认同)

Har*_*eno 7

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

mapDispatchToProps接收dispatchandprops旨在让您将操作创建者绑定到分派,因此当您执行结果函数时,操作就会被分派。

我发现这只会让您不必在组件内执行操作dispatch(actionCreator()),从而使其更易于阅读。

React redux: connect: 参数


Mee*_*eri 7

现在假设有一个 redux 操作:

export function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}
Run Code Online (Sandbox Code Playgroud)

当你导入它时,

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);
Run Code Online (Sandbox Code Playgroud)

正如函数名称所示mapDispatchToProps(),将dispatch操作映射到 props(我们组件的 props)

所以 proponTodoClick是函数的关键mapDispatchToProps,它将进一步委托给调度 action 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);
Run Code Online (Sandbox Code Playgroud)

这确切的意思是

const mapDispatchToProps = dispatch => {
    return {
      addTodo: () => { 
        dispatch(addTodo())
      }
    }
}
Run Code Online (Sandbox Code Playgroud)