web-dev-qa-db-ja.com

connect with / Reduxを使用してthis.propsから簡単なディスパッチを取得する方法は?

接続する単純なReactコンポーネントがあります(単純な配列/状態をマッピングします)。ストアのコンテキストを参照しないようにするには、小道具から直接「ディスパッチ」を取得する方法が必要です。私は他の人がこのアプローチを使用しているのを見ましたが、何らかの理由でこれにアクセスできません:)

現在使用している各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);

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

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]

96
Toran Billups

デフォルトでは、mapDispatchToPropsdispatch => ({ dispatch })です。
したがって、connect()の2番目の引数を指定しないと、コンポーネントにdispatchが小道具として挿入されます。

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対応コンポーネントとRedux非対応コンポーネント間の境界として機能します。これが、通常、bothバウンドアクションクリエーターとdispatchを注入する意味がないと感じる理由です。ただし、これを行う必要があると感じた場合は、お気軽に。

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

// 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を渡すなど、よりカスタムなものが必要な場合は、ニースの短い構文を放棄する必要があります。

270
Dan Abramov

通常は、希望に基づいて組み合わせて一致させることができます。

あなたがcan望むなら、dispatchを小道具として渡す:

export default connect(mapStateToProps, (dispatch) => ({
    ...bindActionCreators({fetchUsers}, dispatch), dispatch
}))(Users);

(非同期関数として)fetchUsersがどのように使用されるのかわかりませんが、通常はbindActionCreatorsのようなものをauto-bindディスパッチに使用します。接続されたコンポーネントでdispatchを直接使用することを心配する必要があります。

dispatchディレクトリの並べ替えを使用して、dumb、reduxのステートレスコンポーネントを組み合わせます。移植性が低下する可能性があります。

5
Davin Tryon

dispatchの一部としてdispatchToPropsを渡すことはできますが、コンポーネント内からstoreまたはdispatchに直接アクセスすることは避けることをお勧めします。接続の2番目の引数dispatchToPropsでバインドされたアクションクリエーターを渡すことで、より良いサービスが得られるようです。

私がここに投稿した例を参照してください https://stackoverflow.com/a/34455431/2644281 コンポーネントが直接知る必要のない「すでにバインドされたアクション作成者」をこのように伝える方法またはストア/ディスパッチに依存しています。

簡単にすみません。詳細を更新します。

1
Erik Aybar