web-dev-qa-db-ja.com

アクション作成者でRedux状態にアクセスしますか?

次のようにします。

export const SOME_ACTION = 'SOME_ACTION';
export function someAction() {
  return {
    type: SOME_ACTION,
  }
}

そしてそのアクションクリエイターで、私はグローバルストアの状態(すべてのリデューサー)にアクセスしたいです。これを行う方が良いですか?

import store from '../store';

export const SOME_ACTION = 'SOME_ACTION';
export function someAction() {
  return {
    type: SOME_ACTION,
    items: store.getState().otherReducer.items,
  }
}

またはこれ:

export const SOME_ACTION = 'SOME_ACTION';
export function someAction() {
  return (dispatch, getState) => {
    const {items} = getState().otherReducer;

    dispatch(anotherAction(items));
  }
}
225
ffxsam

あなたのシナリオが単純なときは、あなたが使うことができます

import store from '../store';

export const SOME_ACTION = 'SOME_ACTION';
export function someAction() {
  return {
    type: SOME_ACTION,
    items: store.getState().otherReducer.items,
  }
}

しかし時々あなたのaction creatorはマルチアクションを引き起こす必要があります

例えば非同期リクエストなのでREQUEST_LOADREQUEST_LOAD_SUCCESSREQUEST_LOAD_FAILアクションが必要です

export const [REQUEST_LOAD, REQUEST_LOAD_SUCCESS, REQUEST_LOAD_FAIL] = [`REQUEST_LOAD`
    `REQUEST_LOAD_SUCCESS`
    `REQUEST_LOAD_FAIL`
]
export function someAction() {
    return (dispatch, getState) => {
        const {
            items
        } = getState().otherReducer;
        dispatch({
            type: REQUEST_LOAD,
            loading: true
        });
        $.ajax('url', {
            success: (data) => {
                dispatch({
                    type: REQUEST_LOAD_SUCCESS,
                    loading: false,
                    data: data
                });
            },
            error: (error) => {
                dispatch({
                    type: REQUEST_LOAD_FAIL,
                    loading: false,
                    error: error
                });
            }
        })
    }
}

注: あなたは redux-thunk を必要とします

24
Nour Sammour

ストアから読み込むのはそれほど悪いことではないことを指摘したいと思います。コンポーネントにすべてを渡してからのパラメーターとして渡すよりも、ストアに基づいて何をすべきかを決めるほうがはるかに便利かもしれません。機能。私はDanに完全に同意します。クライアント側のレンダリングにのみ使用することを100%確信できない限り、storeをシングルトーンとして使用しない方がはるかによいことです(そうでなければバグを追跡するのが難しいかもしれません)。

reduxの冗長性に対処するために、最近ライブラリ を作成しました。すべてをミドルウェアに入れることをお勧めします。したがって、依存性注入としてすべてを使用することをお勧めします。

だから、あなたの例はそのようになります:

import { createSyncTile } from 'redux-tiles';

const someTile = createSyncTile({
  type: ['some', 'tile'],
  fn: ({ params, selectors, getState }) => {
    return {
      data: params.data,
      items: selectors.another.tile(getState())
    };
  },
});

しかし、ご覧のとおり、ここではデータを実際には変更していないため、このセレクタを他の場所で使用して他の場所で組み合わせることができる可能性があります。

3
Bloomca

私は@Bloomcaに同意します。ストアからディスパッチ関数に必要な値を引数として渡すことは、ストアをエクスポートするよりも簡単です。私はここで例を作りました:

import React from "react";
import {connect} from "react-redux";
import * as actions from '../actions';

class App extends React.Component {

  handleClick(){
    const data = this.props.someStateObject.data;
    this.props.someDispatchFunction(data);
  }

  render(){
    return (
      <div>       
      <div onClick={ this.handleClick.bind(this)}>Click Me!</div>      
      </div>
    );
  }
}


const mapStateToProps = (state) => {
  return { someStateObject: state.someStateObject };
};

const mapDispatchToProps = (dispatch) => {
  return {
    someDispatchFunction:(data) => { dispatch(actions.someDispatchFunction(data))},

  };
}


export default connect(mapStateToProps, mapDispatchToProps)(App);
2
Jason Allshorn

これを解決する別の方法を提示します。アプリケーションによっては、これはDanの解決策よりも良くも悪くもあります。

アクションを2つの別々の関数に分割することによって、リデューサーからアクションに状態を取得することができます。最初にデータを要求し、2番目にデータを処理します。 redux-loop を使ってそれを行うことができます。

まず、「データを親切にお願いします」

export const SOME_ACTION = 'SOME_ACTION';
export function someAction() {
    return {
        type: SOME_ACTION,
    }
}

リデューサーで、askをインターセプトし、redux-loopを使用してデータを第2段階のアクションに渡します。

import { loop, Cmd } from 'redux-loop';
const initialState = { data: '' }
export default (state=initialState, action) => {
    switch(action.type) {
        case SOME_ACTION: {
            return loop(state, Cmd.action(anotherAction(state.data))
        }
    }
}

データを入手したら、最初に必要なことをすべて実行します。

export const ANOTHER_ACTION = 'ANOTHER_ACTION';
export function anotherAction(data) {
    return {
        type: ANOTHER_ACTION,
        payload: data,
    }
}

これが誰かに役立つことを願っています。

1
Andrei Cioara

私はここでパーティーに遅れていることを知っていますが、行動で状態を使用したいという自分自身の欲求について意見を求めてここに来て、正しい行動だと思うことに気づいたときに自分自身を形成しました。

これは、セレクターが私にとって最も意味のある場所です。このリクエストを発行するコンポーネントは、選択を通じてそれを発行する時が来たかどうかを伝える必要があります。

export const SOME_ACTION = 'SOME_ACTION';
export function someAction(items) {
  return (dispatch) => {
    dispatch(anotherAction(items));
  }
}

抽象化が漏れているように感じるかもしれませんが、コンポーネントは明らかにメッセージを送信する必要があり、メッセージペイロードには適切な状態を含める必要があります。残念ながら、あなたの質問には具体的な例はありません。セレクターとアクションの「より良いモデル」をそのように処理できるからです。

0
SqueeDee