mapDispatchToPropsとは何ですか?


358

私はReduxライブラリのドキュメントを読んでいましたが、次の例があります。

状態を読み取ることに加えて、コンテナコンポーネントはアクションをディスパッチできます。同様にmapDispatchToProps()dispatch()メソッドを受け取り、プレゼンテーションコンポーネントに注入するコールバックプロップを返す、という関数を定義できます。

これは実際には意味がありません。mapDispatchToPropsすでに持っているのになぜ必要なのmapStateToPropsですか?

また、次の便利なコードサンプルも提供しています。

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

誰かがこの関数が何であるか、そしてなぜそれが有用であるかを素人の言葉で説明できますか?

回答:


577

なぜmapDispatchToProps有用なのか、答えが明確になっていないように思います。

これは実際にはcontainer-componentパターンのコンテキストでのみ答えることができます。これは、最初に「コンテナコンポーネント」、次に「Reactでの使用法」を読むことで最もよく理解できました。

一言で言えば、あなた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>
     }
}

このコンポーネントがどのようにプロップから表示する情報を取得するかを確認します(これはを介してreduxストアから取得されますmapStateToProps)。また、そのアクション関数をプロップから取得します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
)

ご覧いただけるかと思いますが、redux、ディスパッチ、ストア、ステートなどについて知っているのはcontainer 1つです。

componentパターン、中FancyAlerterにはでコールにそのメソッドを取得します:レンダリングがその原料のいずれかについて知る必要はありませんん、onClickボタンの、その小道具を経由して。

そして... mapDispatchToPropsは、コンテナーがその機能を小道具のラップされたコンポーネントに簡単に渡すためにreduxが提供する便利な手段でした。

これはすべて、ドキュメントのtodoの例と、ここでの別の回答に非常に似ていますが、理由を強調するためにパターンに照らしてキャストしようとしました。

(注:内部にアクセスできないという基本的な理由とmapStateToProps同じ目的で使用することはできません。そのため、ラップされたコンポーネントにを使用するメソッドを提供するために使用することはできませんでした。 mapDispatchToPropsdispatchmapStateToPropmapStateToPropsdispatch

彼らがなぜそれを2つのマッピング関数に分割することを選んだのか、私にはわかりません-IEにmapToProps(state, dispatch, props) 両方の機能を持たせるのは面倒だったかもしれません!


1FancyButtonContainer「もの」であることを強調するために、 意図的に明示的にコンテナに名前を付けていることに注意してください。「もの」としてのコンテナのアイデンティティ(および存在)は、省略形で失われることがあります。

export default connect(...) ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

ほとんどの例に示されている構文


5
私はまだ知りたいです:コンポーネント内から直接store.dispatchを呼び出すことで必要な機能を処理できませんでしたか?
pixelpax 2017年

8
@ user2130130なし。それは良いデザインについてです。コンポーネントをstore.dispatchに結合した場合、reduxを除外するか、redxuベースではない場所(または今は考えられない他の場所)で使用したい場合、多くの変更。あなたの質問は、「なぜ「優れた設計手法」に煩わされるのか-コーディングしても同じ機能が得られるのはなぜですか」と一般化しています。mapDispatchToPropsが提供されているため、適切に設計され、明確に分離されたコンポーネントを記述できます。
GreenAsJade 2017年

4
:私は本当にここに取得しないことは何かということですALERT_ACTIONそのアクション機能であるかtypeのアクション関数から返されますか?:/とても困惑している
ジェイミーハットバー2017年

1
@JamieHutber厳密には、ALERT_ACTIONはこの質問とは関係ありません。これはディスパッチへの有効な引数であり、実際のところ、私のコードでは、ディスパッチが使用するオブジェクトを返す「アクションビルダー」からのものです。redux.js.org/ docs / api / Store.html#dispatch。ここでの主なポイントは、ディスパッチを呼び出す方法がコンテナに記述され、コンポーネントのプロパティに渡されることです。コンポーネントは、その小道具からのみ機能を取得します。このパターンでそれを行う「間違った」方法は、ディスパッチをコンポーネントに渡し、コンポーネントで同じ呼び出しを行うことです。
GreenAsJade 2017年

1
小道具として子コンポーネントに渡す必要がある複数のアクションクリエーターがある場合、1つの代替策は、それらをmapDispatchToProps内のbindActionCreatorsでラップすることです(redux.js.org/docs/api/bindActionCreators.htmlを参照)。別の方法は、connect()にアクション作成者のオブジェクトを提供することです。たとえば、connect(mapStateToProps、{actioncreators})、react-reduxは、それらをdispatch()でラップします。
デイブ2017年

81

基本的には省略形です。だから書く必要はありません:

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


ありがとうございました。そもそもディスパッチはどのように小道具に追加されるのでしょうか?
Code Whisperer 2016

14
独自のmapDispatch関数を提供しない場合、Reduxはデフォルトを使用します。そのデフォルトのmapDispatch関数は単にdispatch関数参照を受け取り、それをとして提供しますthis.props.dispatch
markerikson 2016

7
ディスパッチメソッドは、プロバイダーコンポーネント
Diego Haz

55

mapStateToProps()コンポーネントが更新された状態(他のいくつかのコンポーネントによって更新される)を取得するのに役立つユーティリティです。コンポーネントが
mapDispatchToProps()アクションイベント(アプリケーションの状態の変化を引き起こす可能性のあるディスパッチアクション)を起動するのに役立つユーティリティです。


23

mapStateToPropsmapDispatchToPropsおよびライブラリconnectからは、ストアのおよび関数react-reduxにアクセスするための便利な方法を提供します。したがって、基本的には接続はより高次のコンポーネントです。これが意味のある場合は、ラッパーと考えることもできます。したがって、が変更されるたびに新しいが呼び出され、その後、コンポーネントを更新するとrender関数が実行されてコンポーネントがブラウザーにレンダリングされます。また、コンポーネントのKey-Valueも格納します。通常、これらは関数の形式を取ります。このように、あなたは、トリガすることができますあなたのコンポーネントからの変化を、イベントを。statedispatchstatemapStateToPropsstatepropsmapDispatchToPropspropsstateonClickonChange

ドキュメントから:

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) 

また、Reactステートレス関数高次コンポーネントに精通していることを確認してください


ディスパッチは基本的にイベントのようなものですか?
Code Whisperer

2
イベントに関連している可能性があります。ディスパッチ関数であり、アプリケーションの状態を変更する唯一の方法です。mapStateToPropsは、ストアのディスパッチ関数をReactコンポーネントに公開する1つの方法です。また、connectはreduxの一部ではないことに注意してください。実際には、ただのユーティリティであり、react-reduxと呼ばれるボイラープレート削減ライブラリが、reactとreduxで動作します。ストアをroot反応コンポーネントから子に 渡す場合、react-reduxなしで同じ結果を得ることができます。
Vlad Filimon 2016

3

mapStateToPropsstateおよびpropsを受け取り、状態から小道具を抽出してコンポーネントに渡すことができます。

mapDispatchToPropsを受け取りdispatchpropsアクション作成者をディスパッチにバインドして、結果の関数を実行するとアクションがディスパッチされるようにします。

これによりdispatch(actionCreator())、コンポーネント内で行う必要がなくなるため、読みやすくなります。

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


ありがとうございますが、dispatchメソッドの価値は何ですか?それはどこから来たのですか?
Code Whisperer 2016

ああ。ディスパッチすると、基本的にアクションはredux / flux単方向フローを開始します。他の答えはこれよりあなたの質問によく答えたようです。
ハリーモレノ

また、ディスパッチメソッドは、<Provider/>それ自体が提供する拡張機能から来ています。子コンポーネントでディスパッチが利用可能であることを保証するために、独自の高次コンポーネントマジックを実行します。
RicardoMagalhães2017

3

次に、次のような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アクションをプロップ(コンポーネントのプロップ)にマップします

したがって、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())
      }
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.