1. ホーム
  2. javascript

[解決済み] Reduxでコネクトを使ってthis.propsから簡単なディスパッチを取得する方法とは?

2022-10-14 14:26:48

質問

私は接続するシンプルなReactコンポーネントを持っています(シンプルな配列/状態を上にマッピングする)。ストアのコンテキストを参照しないようにするために、私はプロップから直接"dispatch"を取得する方法が欲しいです。私はこのアプローチを使用している他の人を見たことがありますが、何らかの理由でこれにアクセスすることはできません:)

現在使用している各npm依存のバージョンは次のとおりです。

"react": "0.14.3",
"react-redux": "^4.0.0",
"react-router": "1.0.1",
"redux": "^3.0.4",
"redux-thunk": "^1.0.2"

以下は、接続メソッドを持つコンポーネントです。

class Users extends React.Component {
    render() {
        const { people } = this.props;
        return (
            <div>
                <div>{this.props.children}</div>
                <button onClick={() => { this.props.dispatch({type: ActionTypes.ADD_USER, id: 4}); }}>Add User</button>
            </div>
        );
    }
};

function mapStateToProps(state) {
    return { people: state.people };
}

export default connect(mapStateToProps, {
    fetchUsers
})(Users);

reducer を見る必要がある場合 (何もエキサイティングなことはありませんが、ここにあります)

const initialState = {
    people: []
};

export default function(state=initialState, action) {
    if (action.type === ActionTypes.ADD_USER) {
        let newPeople = state.people.concat([{id: action.id, name: 'wat'}]);
        return {people: newPeople};
    }
    return state;
};

私のルータがどのようにreduxで構成されているかを見る必要がある場合

const createStoreWithMiddleware = applyMiddleware(
      thunk
)(createStore);

const store = createStoreWithMiddleware(reducers);

var Route = (
  <Provider store={store}>
    <Router history={createBrowserHistory()}>
      {Routes}
    </Router>
  </Provider>
);

更新

は、私が接続で私自身のディスパッチを省略する場合(現在、私は上記のfetchUsersを表示しています)、私はディスパッチフリーになるように見えます(ちょうどこれが非同期アクションのセットアップが通常動作する方法であるかどうかはわかりません)。人々は混ぜたり合わせたりしているのでしょうか、それとも全てなのか何もないのでしょうか?

[mapDispatchToProps]。

どのように解決するのですか?

デフォルトでは mapDispatchToProps は単に dispatch => ({ dispatch }) .

というわけで、第2引数を指定しない場合は connect() を指定しないと dispatch がコンポーネント内のpropとして注入されます。

にカスタム関数を渡すと mapDispatchToProps に渡すと、その関数で何でもできるようになります。

いくつか例を挙げます。

// inject onClick
function mapDispatchToProps(dispatch) {
  return {
    onClick: () => dispatch(increment())
  };
}

// inject onClick *and* dispatch
function mapDispatchToProps(dispatch) {
  return {
    dispatch,
    onClick: () => dispatch(increment())
  };
}

タイピングの手間を省くために、Reduxでは bindActionCreators() があり、これを回すことができます。

// injects onPlusClick, onMinusClick
function mapDispatchToProps(dispatch) {
  return {
    onPlusClick: () => dispatch(increment()),
    onMinusClick: () => dispatch(decrement())
  };
}

をこの中に入れてください。

import { bindActionCreators } from 'redux';

// injects onPlusClick, onMinusClick
function mapDispatchToProps(dispatch) {
  return bindActionCreators({
    onPlusClick: increment,
    onMinusClick: decrement
  }, dispatch);
}

または、小道具の名前がアクションの作成者の名前と一致する場合は、さらに短くなります。

// injects increment and decrement
function mapDispatchToProps(dispatch) {
  return bindActionCreators({ increment, decrement }, dispatch);
}

もしあなたが望むなら、間違いなく dispatch を手作業で追加することができます。

// injects increment, decrement, and dispatch itself
function mapDispatchToProps(dispatch) {
  return {
    ...bindActionCreators({ increment, decrement }), // es7 spread syntax
    dispatch
  };
}

これを行うべきかどうかについての公式な助言はありません。 connect() は通常、Reduxを意識したコンポーネントと意識していないコンポーネントの境界として機能します。このため、通常、私たちは バインドされたアクションクリエイターと dispatch . しかし、もしあなたがこれをする必要があると感じるなら、自由にやってください。

最後に、今使っているパターンで、呼び出すよりもさらに短いショートカットである bindActionCreators . を返すだけである場合 bindActionCreators を返すだけであれば、このようにする代わりにsoの呼び出しを省略することができます。

// injects increment and decrement
function mapDispatchToProps(dispatch) {
  return bindActionCreators({ increment, decrement }, dispatch);
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(App);

はこのように書くことができます。

export default connect(
  mapStateToProps,
  { increment, decrement } // injects increment and decrement
)(App);

しかし、もっとカスタムなことをしたいときには、この短い構文をあきらめなければなりません。 dispatch を渡すような、よりカスタムなことをしたいときは、この素晴らしい短い構文をあきらめなければなりません。