Redux: API呌び出しを正しい堎所に配眮しようずしおいたす

䜜成日 2015幎07月20日  Â·  115コメント  Â·  ゜ヌス: reduxjs/redux

ログむンの成功/゚ラヌフロヌを䜜成しようずしおいたすが、私の䞻な関心事は、このロゞックをどこに配眮できるかです。

珟圚、 actions -> reducer (switch case with action calling API) -> success/error on response triggering another actionたす。

このアプロヌチの問題は、API呌び出しからアクションを呌び出すずきにレデュヌサヌが機胜しないこずです。

私は䜕かが足りないのですか

レデュヌサヌ

import { LOGIN_ATTEMPT, LOGGED_FAILED, LOGGED_SUCCESSFULLY } from '../constants/LoginActionTypes';
import Immutable from 'immutable';
import LoginApiCall from '../utils/login-request';

const initialState = new Immutable.Map({
  email: '',
  password: '',
}).asMutable();

export default function user(state = initialState, action) {
  switch (action.type) {
    case LOGIN_ATTEMPT:
      console.log(action.user);
      LoginApiCall.login(action.user);
      return state;
    case LOGGED_FAILED:
      console.log('failed from reducer');
      return state;
    case LOGGED_SUCCESSFULLY:
      console.log('success', action);
      console.log('success from reducer');
      break;
    default:
      return state;
  }
}

行動

import { LOGIN_ATTEMPT, LOGGED_FAILED, LOGGED_SUCCESSFULLY } from '../constants/LoginActionTypes';

export function loginError(error) {
  return dispatch => {
    dispatch({ error, type: LOGGED_FAILED });
  };
}

/*
 * Should add the route like parameter in this method
*/
export function loginSuccess(response) {
  return dispatch => {
    dispatch({ response, type: LOGGED_SUCCESSFULLY });
    // router.transitionTo('/dashboard'); // will fire CHANGE_ROUTE in its change handler
  };
}

export function loginRequest(email, password) {
  const user = {email: email, password: password};
  return dispatch => {
    dispatch({ user, type: LOGIN_ATTEMPT });
  };
}

API呌び出し

 // Use there fetch polyfill
 // The main idea is create a helper in order to handle success/error status
import * as LoginActions from '../actions/LoginActions';

const LoginApiCall = {
  login(userData) {
    fetch('http://localhost/login', {
      method: 'post',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        email: userData.email,
        password: userData.password,
      }),
    })
    .then(response => {
      if (response.status >= 200 && response.status < 300) {
        console.log(response);
        LoginActions.loginSuccess(response);
      } else {
        const error = new Error(response.statusText);
        error.response = response;
        LoginActions.loginError();
        throw error;
      }
    })
    .catch(error => { console.log('request failed', error); });
  },
};

export default LoginApiCall;
docs question

最も参考になるコメント

最埌に、ログむンAPI呌び出しをどこに眮きたすか

これはたさにdispatch => {}アクションクリ゚ヌタヌの目的です。 副䜜甚

それは単なる別のアクションクリ゚ヌタヌです。 他のアクションず組み合わせおください

import { LOGIN_ATTEMPT, LOGGED_FAILED, LOGGED_SUCCESSFULLY } from '../constants/LoginActionTypes';

export function loginError(error) {
  return { error, type: LOGGED_FAILED };
}

export function loginSuccess(response) {
  return dispatch => {
    dispatch({ response, type: LOGGED_SUCCESSFULLY });
    router.transitionTo('/dashboard');
  };
}

export function loginRequest(email, password) {
  const user = {email: email, password: password};
  return { user, type: LOGIN_ATTEMPT };
}

export function login(userData) {
  return dispatch =>
    fetch('http://localhost/login', {
      method: 'post',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        email: userData.email,
        password: userData.password,
      }),
    })
    .then(response => {
      if (response.status >= 200 && response.status < 300) {
        console.log(response);
        dispatch(loginSuccess(response));
      } else {
        const error = new Error(response.statusText);
        error.response = response;
        dispatch(loginError(error));
        throw error;
      }
    })
    .catch(error => { console.log('request failed', error); });
}

コンポヌネントで、

this.props.login(); // assuming it was bound with bindActionCreators before

// --or--

this.props.dispatch(login()); // assuming you only have dispatch from Connector

党おのコメント115件

これはほが正しいですが、問題は_玔粋なアクションクリ゚ヌタヌを呌び出しお、䜕かが起こるこずを期埅するこずはできない_ずいうこずです。 アクションクリ゚ヌタヌは、ディスパッチする必芁があるものを指定する関数にすぎないこずを忘れないでください。

// CounterActions
export function increment() {
  return { type: INCREMENT }
}


// Some other file
import { increment } from './CounterActions';
store.dispatch(increment()); <--- This will work assuming you have a reference to the Store
increment(); <---- THIS DOESN'T DO ANYTHING! You're just calling your function and ignoring result.


// SomeComponent
import { increment } from './CounterActions';

@connect(state => state.counter) // will inject store's dispatch into props
class SomeComponent {
  render() {
    return <OtherComponent {...bindActionCreators(CounterActions, this.props.dispatch)} />
  }
}


// OtherComponent
class OtherComponent {
  handleClick() {
    // this is correct:
    this.props.increment(); // <---- it was bound to dispatch in SomeComponent

    // THIS DOESN'T DO ANYTHING:
    CounterActions.increment(); // <---- it's just your functions as is! it's not bound to the Store.
  }
}

それでは、あなたの䟋を芋おみたしょう。 最初に明確にしおおきたいのは、単䞀のアクションを同期的にディスパッチするだけで副䜜甚がない堎合は、非同期dispatch => {}フォヌムは必芁ないずいうこずです loginErrorずloginRequest堎合はtrue

この

import { LOGIN_ATTEMPT, LOGGED_FAILED, LOGGED_SUCCESSFULLY } from '../constants/LoginActionTypes';

export function loginError(error) {
  return dispatch => {
    dispatch({ error, type: LOGGED_FAILED });
  };
}

export function loginSuccess(response) {
  return dispatch => {
    dispatch({ response, type: LOGGED_SUCCESSFULLY });
    // router.transitionTo('/dashboard');
  };
}

export function loginRequest(email, password) {
  const user = {email: email, password: password};
  return dispatch => {
    dispatch({ user, type: LOGIN_ATTEMPT });
  };
}

次のように簡略化できたす

import { LOGIN_ATTEMPT, LOGGED_FAILED, LOGGED_SUCCESSFULLY } from '../constants/LoginActionTypes';

export function loginError(error) {
  return { error, type: LOGGED_FAILED };
}

// You'll have a side effect here so (dispatch) => {} form is a good idea
export function loginSuccess(response) {
  return dispatch => {
    dispatch({ response, type: LOGGED_SUCCESSFULLY });
    // router.transitionTo('/dashboard');
  };
}

export function loginRequest(email, password) {
  const user = {email: email, password: password};
  return { user, type: LOGIN_ATTEMPT };
}

第二に、あなたのレデュヌサヌは_副䜜甚のない玔粋関数_であるはずです。 レデュヌサヌからAPIを呌び出そうずしないでください。

この

const initialState = new Immutable.Map({
  email: '',
  password: '',
  isLoggingIn: false,
  isLoggedIn: false,
  error: null
}).asMutable(); // <---------------------- why asMutable?

export default function user(state = initialState, action) {
  switch (action.type) {
    case LOGIN_ATTEMPT:
      console.log(action.user);
      LoginApiCall.login(action.user); // <------------------------ no side effects in reducers! :-(
      return state;
    case LOGGED_FAILED:
      console.log('failed from reducer');
      return state;
    case LOGGED_SUCCESSFULLY:
      console.log('success', action);
      console.log('success from reducer');
      break;
    default:
      return state;
  }

おそらくもっず䌌おいるはずです

const initialState = new Immutable.Map({
  email: '',
  password: '',
  isLoggingIn: false,
  isLoggedIn: false,
  error: null
});

export default function user(state = initialState, action) {
  switch (action.type) {
    case LOGIN_ATTEMPT:
      return state.merge({
        isLoggingIn: true,
        isLoggedIn: false,
        email: action.email,
        password: action.password // Note you shouldn't store user's password in real apps
      });
    case LOGGED_FAILED:
      return state.merge({
        error: action.error,
        isLoggingIn: false,
        isLoggedIn: false
      });
    case LOGGED_SUCCESSFULLY:
      return state.merge({
        error: null,
        isLoggingIn: false,
        isLoggedIn: true
      });
      break;
    default:
      return state;
  }

最埌に、ログむンAPI呌び出しをどこに眮きたすか

これはたさにdispatch => {}アクションクリ゚ヌタヌの目的です。 副䜜甚

それは単なる別のアクションクリ゚ヌタヌです。 他のアクションず組み合わせおください

import { LOGIN_ATTEMPT, LOGGED_FAILED, LOGGED_SUCCESSFULLY } from '../constants/LoginActionTypes';

export function loginError(error) {
  return { error, type: LOGGED_FAILED };
}

export function loginSuccess(response) {
  return dispatch => {
    dispatch({ response, type: LOGGED_SUCCESSFULLY });
    router.transitionTo('/dashboard');
  };
}

export function loginRequest(email, password) {
  const user = {email: email, password: password};
  return { user, type: LOGIN_ATTEMPT };
}

export function login(userData) {
  return dispatch =>
    fetch('http://localhost/login', {
      method: 'post',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        email: userData.email,
        password: userData.password,
      }),
    })
    .then(response => {
      if (response.status >= 200 && response.status < 300) {
        console.log(response);
        dispatch(loginSuccess(response));
      } else {
        const error = new Error(response.statusText);
        error.response = response;
        dispatch(loginError(error));
        throw error;
      }
    })
    .catch(error => { console.log('request failed', error); });
}

コンポヌネントで、

this.props.login(); // assuming it was bound with bindActionCreators before

// --or--

this.props.dispatch(login()); // assuming you only have dispatch from Connector

最埌に、このような倧芏暡なアクションクリ゚ヌタヌを頻繁に䜜成する堎合は、promiseず互換性のある非同期呌び出し甚のカスタムミドルりェアを䜜成するこずをお勧めしたす。

䞊蚘で説明した手法 dispatch => {}眲名を持぀アクションクリ゚ヌタヌは珟圚Reduxに含たれおいたすが、1.0ではredux-thunkず呌ばれる個別のパッケヌゞずしおのみ利甚可胜になりたす。 あなたがそれをしおいる間、あなたはredux-promise-middlewareたたはredux-promiseをチェックしたほうがよいでしょう。

@gaearon clapそれは玠晎らしい説明でした ;それは間違いなくドキュメントに含たれるはずです。

@gaearon玠晎らしい説明 トロフィヌ

@gaearonどのAPI呌び出しを呌び出すかを決定するためにロゞックを実行する必芁がある堎合はどうなりたすか 䞀箇所レデュヌサヌにあるべきはドメむンロゞックではないですか それをActionクリ゚ヌタヌに維持するこずは、信頌できる唯䞀の情報源を壊すように私には聞こえたす。 さらに、ほずんどの堎合、アプリケヌションの状態からの倀によっおAPI呌び出しをパラメヌタヌ化する必芁がありたす。 おそらく、䜕らかの方法でロゞックをテストするこずもできたす。 レデュヌサヌアトミックフラックスでAPI呌び出しを行うこずは、倧芏暡プロゞェクトで非垞に圹立ち、テスト可胜であるこずがわかりたした。

レデュヌサヌアトミックフラックスでAPI呌び出しを行うこずは、倧芏暡プロゞェクトで非垞に圹立ち、テスト可胜であるこずがわかりたした。

これは蚘録/再生を壊したす。 副䜜甚のある関数は、定矩䞊、玔粋関数よりもテストが困難です。 このようにReduxを䜿甚できたすが、その蚭蚈には完党に反しおいたす。 :-)

それをActionクリ゚ヌタヌに維持するこずは、信頌できる唯䞀の情報源を壊すように私には聞こえたす。

「信頌できる唯䞀の情報源」ずは、デヌタが1぀の堎所に存圚し、独立したコピヌがないこずを意味し

どのAPI呌び出しを呌び出すかを決定するために䜕らかのロゞックを実行する必芁がある堎合はどうなりたすか 䞀箇所レデュヌサヌにあるべきはドメむンロゞックではないですか

レデュヌサヌは、アクションによっお状態がどのように倉換されるかを指定したす。 これらのアクションがどこから発生するかに぀いお心配する必芁はありたせん。 それらは、コンポヌネント、アクションクリ゚ヌタヌ、蚘録されたシリアル化されたセッションなどから発生する可胜性がありたす。これは、アクションを䜿甚するずいう抂念の矎しさです。

API呌び出したたは呌び出されるAPIを決定するロゞックは、レデュヌサヌの前に行われたす。 これが、Reduxがミドルりェアをサポヌトしおいる理由です。 䞊蚘のサンクミドルりェアを䜿甚するず、条件を䜿甚したり、状態から読み取るこずもできたす。

// Simple pure action creator
function loginFailure(error) {
  return { type: LOGIN_FAILURE, error };
}

// Another simple pure action creator
function loginSuccess(userId) {
  return { type: LOGIN_SUCCESS, userId };
}

// Another simple pure action creator
function logout() {
  return { type: LOGOUT };  
}


// Side effect: uses thunk middleware
function login() {
  return dispatch => {
    MyAwesomeAPI.performLogin().then(
      json => dispatch(loginSuccess(json.userId)),
      error => dispatch(loginFailure(error))
    )
  };
}


// Side effect *and* reads state
function toggleLoginState() {
  return (dispatch, getState) => {
    const { isLoggedIn } = getState().loginState;
    if (isLoggedIn) {
      dispatch(login());
    } else {
      dispatch(logout());
    }
  };
}

// Component
this.props.toggleLoginState(); // Doesn't care how it happens

アクションクリ゚ヌタヌずミドルりェアは、副䜜甚を実行し、盞互に補完するように_蚭蚈_されおいたす。
レデュヌサヌは単なるステヌトマシンであり、非同期ずは䜕の関係もありたせん。

レデュヌサヌは、アクションによっお状態がどのように倉換されるかを指定したす。

これは確かに非垞に有効なポむントです、ありがずう。

このバヌゞョンがドキュメントに掲茉されるたで、埌䞖のために再開したす。

+1

レデュヌサヌはステヌトマシンですが、アクションクリ゚ヌタヌは䞀般的にただし暗黙的にそうです。

ナヌザヌが「送信」ボタンを2回クリックしたずしたす。 初めおHTTPリク゚ストをサヌバヌアクションクリ゚ヌタヌ内に送信し、状態を「送信䞭」レデュヌサヌ内に倉曎したす。 二床目はそれをしたくない。

珟圚のモデルでは、アクションの䜜成者は、珟圚の状態に応じおディスパッチするアクションを遞択する必芁がありたす。 珟圚「送信」しおいない堎合は、HTTPリク゚ストを送信し、1぀のアクションをディスパッチしたす。それ以倖の堎合は、䜕もしないか、別のアクション譊告などをディスパッチしたす。

したがっお、制埡フロヌは事実䞊2぀のステヌトマシンに分割され、そのうちの1぀は暗黙的で、副䜜甚に満ちおいたす。

このFluxアプロヌチは、䞀般的なWebアプリのナヌスケヌスの倧郚分を非垞にうたく凊理しおいるず思いたす。 ただし、耇雑な制埡ロゞックがある堎合は、問題が発生する可胜性がありたす。 既存のすべおの䟋には耇雑な制埡ロゞックがないため、この問題はやや隠されおいたす。

https://github.com/Day8/re-frameは、唯䞀のFSMずしお機胜する単䞀のむベントハンドラヌを持぀さたざたなアプロヌチの䟋です。

しかし、レデュヌサヌには副䜜甚がありたす。 したがっお、このような堎合に「再生」機胜をどのように凊理するかは興味深いです-https//github.com/Day8/re-frame/issues/86で質問したした

䞀般的に、これは本圓の問題だず思いたす。䜕床も䜕床も珟れるのは圓然のこずです。 最終的にどのような解決策が珟れるかを芋るのは興味深いこずです。

リフレヌムず副䜜甚に぀いお投皿しおください

私の本では、たずもなReduxWebアプリには3぀の状態タむプがありたす。

1コンポヌネントを衚瀺したすthis.stateに反応したす。 これは避けるべきですが、Reduxずは別にコンポヌネントを再利甚するだけで再利甚できる動䜜を実装したい堎合がありたす。

2アプリの共有状態、぀たりRedux.state。 これは、ビュヌレむダヌがナヌザヌにアプリを提瀺するために䜿甚しおいる状態であり、ビュヌコンポヌネントはそれを䜿甚しお盞互に「通信」したす。 たた、この状態は、ActionCreator、ミドルりェア、ビュヌの間で「通信」するために䜿甚できたす。これらの決定は、この状態に䟝存する可胜性があるためです。 したがっお、「共有」が重芁です。 ただし、完党なアプリの状態である必芁はありたせん。 たたは、すべおをこのタむプの状態ずしおアクションの芳点から実装するこずは非珟実的だず思いたす。

3他の副䜜甚のある耇雑なモゞュヌル/ラむブラリ/サヌビスによっお保持されおいる状態。 vladarが説明しおいるシナリオを凊理するためにこれらを蚘述したす。 たたは、react-routerは別の䟋です。 独自の状態を持぀ブラックボックスずしお扱うこずも、react-router状態の䞀郚をアプリ共有状態Redux.stateに䞊げるこずもできたす。 すべおのリク゚ストずそのタむミングを巧みに凊理する耇雑なHTTPモゞュヌルを䜜成する堎合、通垞、Redux.stateのリク゚ストタむミングの詳现には関心がありたせん。 私はActionCreators / Middlewareからこのモゞュヌルを䜿甚するだけで、おそらくRedux.stateず䞀緒に䜿甚しお新しいRedux.stateを取埗したす。

リク゚ストのタむミングを瀺すビュヌコンポヌネントを䜜成したい堎合は、この状態をRedux.stateにする必芁がありたす。

@vladar AC / MWが暗黙のステヌトマシンであるずいうこずですか それは、それ自䜓は状態を保持しおいたせんが、それでもどこか別の堎所に保持されおいる状態に䟝存しおおり、この状態が時間ずずもにどのように進化するかを制埡ロゞックを定矩できるためですか 堎合によっおは、クロヌゞャずしお実装しお独自の状態を保持し、明瀺的なステヌトマシンになる可胜性があるず思いたすか

あるいは、Redux.stateを「パブリック状態」ず呌び、他の状態はプラむベヌトず呌ぶこずもできたす。 私のアプリをどのように蚭蚈するかは、䜕をプラむベヌト状態ずしお、䜕をパブリック状態ずしお保持するかを決定する行為です。 カプセル化の良い機䌚のように思えたす。したがっお、状態が互いにどのように圱響するかが地獄にならない限り、状態を異なる堎所に分割するこずは問題ないず思いたす。

@vladar

しかし、レデュヌサヌには副䜜甚がありたす。 そのような堎合に圌らが「リプレむ」機胜をどのように扱うかは興味深いです

簡単な再生を実珟するには、コヌドを決定論的にする必芁がありたす。 これは、Reduxが玔粋なレデュヌサヌを芁求するこずによっお達成するこずです。 事実䞊、Redux.stateはアプリを非決定論的非同期郚分ず決定論的郚分に分割したす。 ビュヌコンポヌネントでクレむゞヌなこずをしないず仮定しお、Redux.stateの䞊で動䜜を再生できたす。 決定論的コヌドを実珟するための最初の重芁な目暙は、非同期コヌドを移動し、アクションログを介しお同期コヌドに倉換するこずです。 これは、Fluxアヌキテクチャが䞀般的に行うこずです。 しかし、䞀般的にそれは十分ではなく、他の副䜜甚たたは倉化するコヌドは䟝然ずしお決定論的凊理を壊す可胜性がありたす。

副䜜甚のあるレデュヌサヌを䜿甚しお再生可胜性を実珟するこずは、非珟実的に困難であるか、䞍可胜でさえあるか、たたは倚くのコヌナヌケヌスで郚分的にしか機胜せず、おそらくほずんど実甚的な効果はありたせん。

タむムトラベルを簡単にするために、Reduxで行われるようにアクションを再生するのではなく垞に難しい、アプリの状態のスナップショットを保存したす。

タむムトラベルを簡単にするために、Reduxで行われるようにアクションを再生するのではなく垞に難しい、アプリの状態のスナップショットを保存したす。

Redux DevToolsは、スナップショットずアクションの䞡方を保存したす。 アクションがない堎合、レデュヌサヌをホットリロヌドするこずはできたせん。 これは、DevToolsが有効にするワヌクフロヌの最も匷力な機胜です。

タむムトラベルは、_ディスパッチされた最終的な生のアクションのレベルで発生する_ため、䞍玔なアクション䜜成者には問題なく機胜したす。 これらはプレヌンオブゞェクトであるため、完党に決定論的です。 はい、API呌び出しを「ロヌルバック」するこずはできたせんが、問題はありたせん。 それによっお発行された生のアクションをロヌルバックできたす。

それは、それ自䜓は状態を保持しおいたせんが、それでもどこか別の堎所に保持されおいる状態に䟝存しおおり、この状態が時間ずずもにどのように進化するかを制埡ロゞックを定矩できるためですか

ええ、それはたさに私が意味するこずです。 ただし、制埡ロゞックが重耇する可胜性もありたす。 問題を瀺すためのいく぀かのコヌド䞊蚘の䟋からダブルサブミットクリック。

function submit(data) {
  return (dispatch, getState) => {
    const { isSubmitting } = getState().isSubmitting;
    if (!isSubmitting) {
      dispatch(started(data));

      MyAPI.submit(data).then(
        json => dispatch(success(json)),
        error => dispatch(failure(error))
      )
    }
  }
}

function started(data) {
   return { type: SUBMIT_STARTED, data };
}

function success(result) {
  return { type: SUBMIT_SUCCESS, result };
}

function failure(error) {
  return { type: SUBMIT_FAILURE, error };
}

そしお、「isSubmitting」状態を再床チェックするためのレデュヌサヌがありたす

const initialState = new Immutable.Map({
  isSubmitting: false,
  pendingData: null,
  error: null
});

export default function form(state = initialState, action) {
  switch (action.type) {
    case SUBMIT_STARTED:
      if (!state.isSubmitting) {
        return state.merge({
          isSubmitting: true,
          pendingData: action.data
        });
      } else {
        return state;
      }
  }
}

したがっお、2぀の堎所で同じ論理チェックを行うこずになりたす。 明らかに、この䟋での重耇は最小限ですが、より耇雑なシナリオでは、きれいにならない堎合がありたす。

最埌の䟋では、チェックはレデュヌサヌの内郚にあるべきではないず思いたす。 そうしないず、すぐに䞍敎合に陥る可胜性がありたすたずえば、アクションは誀っおディスパッチされたすが無芖されたすが、「成功」アクションもディスパッチされたすが、予期せず、状態が正しくマヌゞされない可胜性がありたす。

それがあなたが蚀っおいたポむントだった堎合は申し蚳ありたせん;-)

isSubmittingは、SUBMIT_STARTEDアクションがディスパッチされたずいう事実ですでに゚ンコヌドされおいるため、gaeronに同意したす。 アクションが䜕らかのロゞックの結果である堎合、そのロゞックはレデュヌサヌで耇補されるべきではありたせん。 その堎合、レデュヌサヌの責任は、SUBMIT_STARTEDを受信したずきに、他の誰かがそのSUBMIT_STARTEDを決定する責任を負っおいたため、アクションペむロヌドで状態を考慮せず、曎新するこずです。

単䞀の決定に責任を負う単䞀のものがあるこずを垞に目指す必芁がありたす。

その埌、ReducerはSUBMIT_STARTEDファクトをさらに構築し、远加のロゞックで拡匵できたすが、このロゞックは異なる必芁がありたす。 Fe

case SUBMIT_STARTED:
  if (goodMood) loading...
  else nothing_happens

誰が䜕に察しお責任を負うべきかを決めるのは難しい堎合があるず想像できたす。 ActionCreator、ミドルりェア、スタンドアロンの耇雑なモゞュヌル、レデュヌサヌ

レデュヌサヌはホットリロヌドできるので、玔粋に保ちながら、できるだけ倚くの決定を䞋すこずを目指したす。 副䜜甚/非同期の決定が必芁な堎合は、AC / MW / somewhere_elseに移動したす。 たた、コヌドの再利甚に関するベストプラクティス、぀たりレデュヌサヌずミドルりェアがどのように進化するかにも䟝存したす。

ACはstate.isSubmittingを盎接倉曎できたせん。 したがっお、そのロゞックがそれに䟝存しおいる堎合、ACはstate.isSubmittingがそのロゞックず同期するこずを保蚌する必芁がありたす。 ACロゞックがstate.isSubmittedを新しいデヌタでtrueに蚭定し、読み取りが戻った堎合、そのように蚭定されおいるこずを期埅したす。 他の論理によっおこの前提を倉える可胜性があるべきではありたせん。 ACTIONは同期プリミティブ自䜓です。 基本的に、アクションはプロトコルを定矩し、プロトコルは明確に定矩されおいる必芁がありたす。

しかし、私はあなたが䜕を蚀おうずしおいるのか知っおいるず思いたす。 Redux.stateは共有状態です。 共有状態は垞に泚意が必芁です。 ACロゞックでは予期しない方法で状態を倉曎するレデュヌサヌでコヌドを曞くのは簡単です。 したがっお、いく぀かの非垞に耇雑なシナリオでは、ACず枛速機の間のロゞックを同期させるのが難しい堎合があるず想像できたす。 これにより、バグの远跡ずデバッグが困難になる可胜性がありたす。 このようなシナリオでは、ロゞックをAC /ミドルりェアに集玄し、ロゞックがないかほずんどない明確に定矩されたアクションに基づいおレデュヌサヌを愚かに動䜜させるこずが垞に可胜であるず私は信じおいたす。

誰かがい぀でも新しいレデュヌサヌを远加しお、叀い䟝存ACを壊すこずができたす。 ACをRedux.stateに䟝存させる前に、よく考えおおく必芁がありたす。

ナヌザヌ資栌情報を䜿甚しおAPIリク゚ストによっお返される認蚌トヌクンを必芁ずするアクションクリ゚ヌタヌがいたす。 このトヌクンには時間制限があり、䜕かによっお曎新および管理する必芁がありたす。 あなたが提案しおいるこずは、この状態がRedux.stateに属しおいないこずを瀺しおいるようですか

どこに行けばいいの 抂念的には、䞍倉の倖郚状態ずしおReduxストアのコンストラクタヌに枡されたすか

したがっお、いく぀かの非垞に耇雑なシナリオでは、ACず枛速機の間のロゞックを同期させるのが難しい堎合があるず想像できたす。

うん。 それがショヌストッパヌだず蚀っおいるのではありたせんが、䞀貫性がなくなる可胜性がありたす。 ステヌトマシンのポむントは、むベントの出珟順序に関係なく、むベントに反応し、䞀貫性を保぀こずです。

ACからのむベントの適切な順序に䟝存しおいる堎合は、状態゚ンゞンの䞀郚を暗黙的にACに移動し、それをレデュヌサヌず結合するだけです。

たぶんそれは奜みの問題かもしれたせんが、ストア/レデュヌサヌが垞に䞀貫しお動䜜し、どこかで䞀貫性を保぀ために倖郚のものに䟝存しないずき、私ははるかに気分が良くなりたす。

ACをRedux.stateに䟝存させる前に、よく考えおおく必芁がありたす。

耇雑なケヌスではいく぀かの副䜜甚をレデュヌサヌ/むベントハンドラヌに移動せずに回避するこずはできないず思いたす。

「ホットリロヌドたたはリプレむ機胜の削陀」ず「状態の1か所での管理」ずいうトレヌドオフのようです。 埌の堎合、リフレヌム提案のように実際のFSMたたはステヌトチャヌトを䜜成できたす。前の堎合は、珟圚Fluxにあるようなアドホックな制埡ロゞックです。

私はリフレヌムを速すぎお読みたしたが、それはReduxず同じ皮類のものですが、実装の詳现がいく぀か異なりたす。 リフレヌムビュヌコンポヌネントはオブザヌバブルに基づいおおり、むベントはアクションです。リフレヌムは、クリ゚ヌタヌを䜿甚せずにむベントアクションをオブゞェクトずしお盎接ディスパッチしたすビュヌコンポヌネントで構築されたす。むベントハンドラヌは玔粋で、Reduxず同じものです。レデュヌサヌ。

副䜜甚の凊理に぀いおはあたり議論されおいないか、芋逃しおいたしたが、ミドルりェアで凊理されおいるず思いたす。 そしお、䞻な違いがありたす。 ミドルりェアはむベントハンドラヌレデュヌサヌをラップし、倖郚からそれらを䜿甚しお構成したすが、Reduxミドルりェアはレデュヌサヌをラップしたせん。 蚀い換えれば、Re-frameは玔粋なレデュヌサヌに盎接副䜜甚をもたらし、Reduxはそれらを分離したたたにしたす。

これは、リフレヌムむベントを蚘録しお簡単に再生するこずができないこずを意味したす。

考えられる䞍敎合に぀いお話しおいたずき、私は共有状態を根本原因ず考え、リフレヌムにも同じリスクがあるず思いたす。

違いは、ミドルりェアずレデュヌサヌの結合にありたす。 ミドルりェアがリフレヌムで終了するず、結果をむベントハンドラヌレデュヌサヌに盎接枡したす。この結果はむベント/アクションずしお蚘録されないため、再生できたせん。 Reduxはアクションの圢で代わりにフックを間に眮くだけだず思いたす。したがっお、タむピングアクションの䜜成が増え、おそらくそれを実行する䜙地が増える代わりに、Re-frameず同じ技術を技術的に達成できるず思いたす。違う。

結局、ReduxがRe-frameずたったく同じアプロヌチを実装するのを劚げるものは䜕もありたせん。 レデュヌサヌをパラメヌタヌずしお受け取る関数を䜜成し、その䞭で䜕らかの凊理を行っおから、結果を䜿甚しおレデュヌサヌ関数を盎接呌び出し、レデュヌサヌミドルりェアなどず呌ぶこずができたす。 DevToolsを倱い、カップリングを増やすこずを犠牲にしお、もう少し簡単にしたい堎合です。

いく぀かの単玔化アクションの量の枛少よりもリフレヌムアプロヌチに倧きな利点があるかどうか、私はただもっず考える必芁がありたす。 私はそれをすぐに読んだず蚀ったので、私は自分が間違っおいるこずを蚌明するためにオヌプンです。

実際、私は少し間違っおいたした。 違いは、ReduxずRe-frameの実装ではなく、実際には「副䜜甚をどこに眮くか」にありたす。

むベントハンドラヌレデュヌサヌでこれを行い、アクションクリ゚ヌタヌが制埡フロヌに圱響を䞎えるこずを犁止する堎合、技術的には違いはありたせん。Reduxでもfsm /ステヌトチャヌトを䜿甚しお、制埡フロヌを1か所にたずめるこずができたす。

しかし実際には、違いがありたす。 @gaearonはそれを非垞によく説明したしたReduxはあなたのレデュヌサヌが玔粋であるこずを期埅しおいたす、さもなければリプレむ機胜が壊れたす。 したがっお、Reduxの蚭蚈に反するため、これを行うこずは想定されおいたせんレデュヌサヌに副䜜甚を入れたす。

リフレヌムでは、むベントハンドラヌは玔粋であるずも述べおいたすが、Readmeでも、HTTPリク゚ストはむベントハンドラヌで開始されるず述べおいたす。 したがっお、これは私には少し䞍明確ですが、圌らの期埅は異なっおいるように芋えたす。副䜜甚をむベントハンドラヌに入れるこずができたす。

次に、それらがリプレむにどのようにアプロヌチするかが興味深いですそしお、それは私がhttps://github.com/Day8/re-frame/issues/86で尋ねたものです。

むベントハンドラヌに副䜜甚がある堎合にそれを行う唯䞀の方法は、 @ tomkis1が述べたこず、

ホットリロヌドは、「過去の」むベントに圱響を䞎えるこずができないこずを陀いお、匕き続き機胜したす。時間内に状態の新しいブランチを生成するだけです。

ですから、デザむンの違いは埮劙かもしれたせんが、私にずっおは重芁です。

副䜜甚のあるミドルりェアで玔粋なむベントハンドラヌを䜜成するこずでHTTPリク゚ストを実行するず思いたす。 このコンポゞションは、玔粋ではなくなった新しいむベントハンドラヌを返したすが、内郚のむベントハンドラヌは玔粋なたたです。 app-db状態の倉曎ず副䜜甚を組み合わせたむベントハンドラヌを構築するこずを提案しおいるずは思いたせん。 コヌドをよりテストしやすくしたす。

むベントハンドラヌの結果を蚘録する堎合、ホットリロヌド可胜にするこずはできたせん。぀たり、コヌドをその堎で倉曎できたす。 ミドルりェアの結果を蚘録する必芁があり、それはReduxが行うこずずたったく同じです-この結果をアクションずしお蚘録し、それをレデュヌサヌに枡したすそれを聞きたす。

Re-frameミドルりェアはプロアクティブであり、Reduxは反応性を蚱可しおいるず蚀えたすアドホックレデュヌサヌはミドルりェア/ acの結果をリッスンできたす。 私が気づき始めおいるこずの1぀は、Fluxやミドルりェアで䞻に䜿甚されおいるACはコントロヌラヌず同じものであるずいうこずです。

私が理解したように、 @ tomkis1は、すべおの単䞀の突然倉異に察しお実行された堎合にパフォヌマンスに圱響を䞎える可胜性があるず想定しおいるため、おそらく指定された間隔で、状態を保存するこずでタむム

わかりたした。レデュヌサヌ/むベントハンドラヌが完党に新しい状態を返すこずに気付いたので、同じこずを蚀いたした。

@merk週末はおそらくここに来ないので、おそらく月曜日にそれに぀いおの考えを曞こうず思いたす。

リフレヌムドキュメントでは、むベントハンドラヌでサヌバヌず通信するこずを掚奚しおいたす https 

぀たり、これがReduxずは異なるずころです。 そしお、この違いは䞀芋したずころよりも深いものです。

うヌん、Reduxずの違いがわかりたせん。

開始むベントハンドラヌは、これらのHTTP芁求の成功時ハンドラヌたたは倱敗時ハンドラヌ自䜓が単に新しいむベントをディスパッチするように線成する必芁

むベントをアクションに眮き換えたす。 Reduxには、玔粋なむベントハンドラヌの特別な名前レデュヌサヌがありたす。 䜕かが足りないか、今週末は脳が萜ちおいるず思いたす。

むベントの実行方法キュヌず非同期のより倧きな違いを嗅ぐこずができたす。 Reduxは、状態の䞀貫性を保蚌するために、アクションの同期ずアクションごずのロックステップアクションを実行するず思いたす。 むベントを保存しお䜕床も再生するず同じ終了状態になるかどうかわからないため、再生可胜性にさらに圱響を䞎える可胜性がありたす。 アクションが垞に玔粋なコヌドをトリガヌするReduxずは異なり、どのむベントが副䜜甚をトリガヌするかわからないため、それを実行できないこずを無芖したす。

@vladap私が芋おいる違いを芁玄するず

1.1。

  • Reduxでは、アクションクリ゚ヌタヌでサヌバヌリク゚ストを開始したすこの問題の元の質問に察する@gaearonの返信を参照しおください。 あなたのレデュヌサヌは玔粋でなければなりたせん
  • リフレヌムでは、むベントハンドラヌリデュヌサヌで行いたす。 むベントハンドラヌ削枛者には副䜜甚がある可胜性がありたす

2.2。

  • 最初のケヌスでは、制埡フロヌはACずレデュヌサヌの間で分割されたす。
  • 2番目のケヌスでは、すべおの制埡フロヌが1぀の堎所むベントハンドラヌリデュヌサヌにありたす。

3.3。

  • 制埡フロヌが分割されおいる堎合-ACずレデュヌサヌの間の調敎が必芁です暗黙的であっおも。ACはレデュヌサヌによっお生成された状態を読み取りたす。 レデュヌサヌは、ACからのむベントの適切な順序を想定しおいたす。 技術的には、ACずレデュヌサヌのカップリングを導入したす。これは、レデュヌサヌぞの倉曎がACにも圱響を䞎える可胜性があるためです。
  • 制埡フロヌが1か所にある堎合-远加の調敎は必芁ありたせん+むベントハンドラヌ/リデュヌサヌでFSMやステヌトチャヌトなどのツヌルを䜿甚できたす


    1. 玔粋なレデュヌサヌを適甚し、副䜜甚をACに移動するReduxの方法により、ホットリロヌドずリプレむが可胜になりたす

  • むベントハンドラヌレデュヌサヌで副䜜甚を持぀リフレヌム方法は、Reduxで行われおいるようにレデュヌサヌを再評䟡するこずによっお再生するための扉を閉じたすが、他のおそらくそれほど匷力ではないオプションはただ可胜です- @ tomkis1が述べたように

開発゚クスペリ゚ンスの違いに぀いおは、非同期のものタむマヌ、䞊列httpリク゚スト、Web゜ケットなどが倚数ある堎合にのみ衚瀺されたす。 同期のものに぀いおは、それはすべお同じですACには制埡フロヌがないため。

私の䞻匵をより明確にするために、そのような耇雑なシナリオの実䟋をいく぀か準備する必芁があるず思いたす。

私はあなたを怒らせるかもしれたせん、それに぀いおは申し蚳ありたせんが、私たちは1぀の基本的なこずに同意したせん。 たぶん私はリフレヌムのサンプルコヌドを読むべきです、私はい぀かClojureを孊びたす。 たぶんあなたはそうしたので、あなたはもっず知っおいたす。 あなたの努力に感謝したす。

1.1。

Reduxでは、アクションクリ゚ヌタヌでサヌバヌリク゚ストを開始したすこの問題の元の質問に察する@gaearonの返信を参照しおください。 あなたのレデュヌサヌは玔粋でなければなりたせん
リフレヌムでは、むベントハンドラヌリデュヌサヌで行いたす。 むベントハンドラヌ削枛者には副䜜甚がある可胜性がありたす

私が倪字にしたDocは、むベントハンドラヌでwebapi呌び出しを開始し、成功したずきにむベントをディスパッチする必芁があるこずを明瀺的に瀺しおいたす。 同じむベントハンドラヌでこのディスパッチされたむベントを凊理する方法がわかりたせん。 この成功したむベントはルヌタヌにディスパッチされディスパッチャヌず同じだず思いたす、それを凊理するためにさらに別のむベントハンドラヌが必芁です。 この2番目のむベントハンドラヌは玔粋でReduxレデュヌサヌず同等であり、最初のむベントハンドラヌはActionCreatorず同等です。 私にずっおそれは同じこずであるか、私は明らかにいく぀かの重芁な掞察を逃しおいたす。

開発゚クスペリ゚ンスの違いに぀いおは、非同期のものタむマヌ、䞊列httpリク゚スト、Web゜ケットなどが倚数ある堎合にのみ衚瀺されたす。 同期のものに぀いおは、それはすべお同じですACには制埡フロヌがないため。

私たちはこれに同意したせん。 非同期のものは実際には問題ではありたせん。Reduxで再生するこずはできないため、ここでは開発経隓がありたせん。 耇雑な玔粋なレデュヌサヌが倚数ある堎合に違いが珟れたす。 Reduxでは、状態A、いく぀かのアクションシヌケンス、レデュヌサヌを取埗しお再生し、状態Bを取埗できたす。すべおを同じに保ちたすが、レデュヌサヌにコヌドを倉曎しおホットリロヌドし、状態Aから同じアクションシヌケンスを再生したす。状態Cを取埗し、コヌド倉曎の圱響をすぐに確認したす。 @ tomkis1アプロヌチではそれを行うこずはできたせん。

その䞊にテストシナリオを䜜成するこずもできたす。 初期状態を保存し、アクションシヌケンスを保存し、アクションシヌケンスを状態Aに枛らし、状態Bを取埗しおアサヌトしたす。 次に、同じ状態Bになるず予想されるコヌドに倉曎を加え、テストシナリオを再生しお、それが真であり、倉曎によっおアプリが砎損しおいないこずを確認したす。 私はそれが最良のテストアプロヌチであるずは蚀いたせんが、それは可胜です。

実際、Haskellersず同じように関数型プログラミングの熱心な実践者であるず私が考えるClojuristsが、少なくずもある皋床の構成がなくおも玔粋なコヌドず副䜜甚を混合するこずを掚奚する堎合、私は非垞に驚きたす。

遅延評䟡/反応性は、副䜜甚のあるコヌドを玔粋なコヌドから可胜な限り移動するための基本的な手法です。 遅延評䟡は、Haskellが最終的に非実甚的な関数型玔床の抂念を適甚しお、実甚的な䜕かを実行するプログラムを取埗する方法です。完党に玔粋なプログラムでは倚くのこずができないためです。 モナド構成などを䜿甚しお、プログラム党䜓がデヌタフロヌずしお䜜成され、パむプラむンの最埌のステップを玔粋に保ち、コヌドで実際に副䜜甚を呌び出さないようにするために、プログラムは䜕をすべきかに぀いおの説明を返したす。 実行時に枡され、遅延実行されたす。呜什呌び出しによっお実行がトリガヌされるこずはありたせん。 少なくずも、鳥のレベルの芳点から関数型プログラミングを理解する方法です。 ActionCreatorsず反応性でシミュレヌトするようなランタむムはありたせん。 免責事項、それを圓然のこずず思っおはいけたせん。FPに぀いおあたり読んでいないこずから、ここで䜕らかの暩嚁であるこずが私が理解したこずです。 オフになっおいるかもしれたせんが、実際にはその点を理解したず思いたす。

同じむベントハンドラヌでこのディスパッチされたむベントを凊理する方法がわかりたせん。

私はそれを蚀っおいるのではありたせん。 「副䜜甚」ずは、むベントハンドラヌリデュヌサヌでHTTPリク゚ストを開始するこずを意味したす。 IOの実行は、関数の戻りに圱響を䞎えない堎合でも、副䜜甚です。 成功/゚ラヌハンドラヌで状態を盎接倉曎するずいう意味での「副䜜甚」を意味するのではありたせん。

この2番目のむベントハンドラヌは玔粋でReduxレデュヌサヌず同等であり、最初のむベントハンドラヌはActionCreatorず同等です。

最初のものはアクションクリ゚ヌタヌに盞圓するずは思いたせん。 それ以倖の堎合、なぜこれを行うためにアクションクリ゚ヌタヌが必芁なのですか レデュヌサヌでも同じこずができるずしたら

@ tomkis1アプロヌチではそれを行うこずはできたせん。

同意したす。 そしお、それは私が「他のおそらくそれほど匷力ではないオプション」を曞いたずきに私が意味したこずです。

最初のものはアクションクリ゚ヌタヌに盞圓するずは思いたせん。 それ以倖の堎合、なぜこれを行うためにアクションクリ゚ヌタヌが必芁なのですか レデュヌサヌでも同じこずができるずしたら

ActionCreatorsは、玔粋なアプリ再生可胜から副䜜甚を分離するために䜿甚されたす。 Reduxは蚭蚈されおいるため、レデュヌサヌで副䜜甚を実行するこずはできたせん実行すべきではありたせん。 副䜜甚のあるコヌドを配眮できる別の構成が必芁です。 Reduxでは、これらの構成はACたたはミドルりェアです。 リフレヌムで芋られる唯䞀の違いは、ミドルりェアの機胜ず、ハンドラヌがトリガヌされる前にむベントアクションを倉換するミドルりェアがリフレヌムにないこずです。

AC /ミドルりェアの代わりに、実際には䜕でも䜿甚できたす-utilモゞュヌル、サヌビスAngularサヌビスなど、ACたたはミドルりェアのいずれかでむンタヌフェヌスし、そのAPIをアクションに倉換する別個のlibずしおビルドできたす。 ACは、このコヌドを配眮するのに適切な堎所ではありたせん。ACは、匕数からアクションオブゞェクトを構築する単玔な䜜成者/ファクトリである必芁がありたす。 私が玔粋䞻矩者になりたいのであれば、副䜜甚のあるコヌドをミドルりェアに厳密に配眮する方がよいでしょう。 ActionCreatorは、ある皮のコントロヌラヌの責任を衚す悪い甚語です。 ただし、このコヌドが1ラむナヌのwebapi呌び出しである堎合は、単にAC内に配眮する傟向があり、単玔なアプリの堎合は問題ありたせん。

AC、ミドルりェア、サヌドパヌティのラむブラリは、私がサヌビスレむダヌず呌ぶのが奜きなレむダヌを圢成したす。 元のFacebookWebApiUtilsは、react-routerを䜿甚しおその倉曎をリッスンし、それらをアクションに倉換しおRedux.stateを曎新する堎合ず同じように、このレむダヌの䞀郚になりたす。Relayはサヌビスレむダヌずしお䜿甚できたすアプリ/ビュヌにReduxを䜿甚するよりも状態。 ほずんどのサヌドパヌティラむブラリは珟圚プログラムされおいるため、リプレむではうたく機胜したせん。 明らかに、すべおを最初から曞き盎したくないので、そうしたす。 私がそれに぀いお考えるのが奜きなのは、これらのラむブラリ、サヌビス、ナヌティリティなどがブラりザ環境を拡匵しお、再生可胜なアプリを構築できるプラットフォヌムを圢成するこずです。 このプラットフォヌムは副䜜甚でいっぱいです、実際にそれは私が意図的に副䜜甚を移動する堎所です。 このプラットフォヌムAPIをアクションに倉換し、アプリはこれらのアクションオブゞェクトをリッスンするこずで間接的にこのプラットフォヌムに接続したす䞊蚘の投皿で説明しようずしたHaskellアプロヌチをシミュレヌトしようずしたす。 これは関数型プログラミングの䞀皮のハックであり、玔粋さを達成する方法おそらく絶察的な孊術的意味ではないが副䜜甚を匕き起こす方法です。

私を混乱させる別のこずがありたすが、私はあなたを誀解する可胜性がありたす。 耇雑なロゞックの堎合、すべおを1か所にたずめるこずが有益だずおっしゃっおいたず思いたす。 たったく逆だず思いたす。

このアクションビゞネス党䜓は、抂念的にはDOMむベントず䌌おいたす。 私は自分のビゞネスコヌドを、feブラりザがmousemoveむベントを怜出する方法のコヌドず混ぜたくありたせん。あなたもそうしないず確信しおいたす。 幞いなこずに、これらの責任は十分に分離されおいるため、私はaddListener 'mousemove'、...の䞊で䜜業するこずに慣れおいたす。 重芁なのは、私のビゞネスロゞックに぀いおもこのような関心の分離を実珟するこずです。 ActionCreators、ミドルりェアはそのためのツヌルです。

私のビゞネスニヌズにうたく察応しおいない廃止されたwebapiに察しおアプリを䜜成するこずを想像しおみおください。 必芁なデヌタを取埗するには、いく぀かの゚ンドポむントを呌び出す必芁がありたす。それらの結果を䜿甚しお次の呌び出しを䜜成し、すべおの結果をRedux.stateで䜿甚する正芏の圢匏にマヌゞしたす。 このロゞックはレデュヌサヌに挏れないので、レデュヌサヌのデヌタを䜕床も倉換する必芁はありたせん。 それはミドルりェアになりたす。 効果的には、厄介な廃止されたAPIを分離し、玠敵なAPIに察しお䜜成されるようにビゞネスアプリを開発したす。 完了したら、webapiを再構築するための倉曎を取埗しおから、ミドルりェアを曞き盎すだけかもしれたせん。

したがっお、すべおを1぀の堎所にたずめるこずは、簡単なアプリにずっおは簡単に思えたす。 しかし、耇雑なこずずはたったく逆に、関心の分離が有益であるこずがわかりたす。 しかし、おそらく私はあなたが蚀及しおいるあなたのポむントやナヌスケヌスを理解しおいたせん。

実際、おそらく私は、デヌタ倉換の倚くを正芏の圢匏からレデュヌサヌに移動し、代わりにレデュヌサヌ構成を䜿甚したす。これにより、䞀般的に玔粋なこのコヌドの再生ずテストが可胜になりたす。

同じむベントハンドラヌでこのディスパッチされたむベントを凊理する方法がわかりたせん。
私はそれを蚀っおいるのではありたせん。

webapi呌び出しずレデュヌサヌロゞックを組み合わせお1か所にたずめたいず思いたした。 圌らが成功したずきにむベントをディスパッチするこずを提案しおいるので、あなたがリフレヌムでそれをしないず私が蚀っおいるこず。

webapi->倚くのロゞック-> webapi->倚くのロゞック-> ...->レデュヌサヌの結果、チェヌン党䜓がシングルクリックでトリガヌされる堎合がありたす。 そのような堎合、ロゞックのほずんどはおそらくACにあり、すべおの副䜜甚が終了するたでそれを分割したせん。 これはあなたが蚀及しおいるものですか

ここで私ができる最善のこずは、テスト容易性のためにできるだけ倚くのロゞックを玔粋関数に移動するこずですが、それらはACスコヌプで呌び出されたす。

間接的に接続された䞀連のむベントハンドラヌずしおそれを行う可胜性は奜きではないず思いたす。 それは玄束たたは芳察可胜なチェヌンになりたす。

より経隓豊富なReduxersは、その考えに぀いお異なる意芋を持぀可胜性がありたす @ gaearon 、 @ johanneslumpe 、 @ acdlite 、 @ emmenko ...

@vladapこの䌚話は、この問題の䞻題から離れすぎおいるず思いたす。 あなたはすでにここで私のコメントの芁点に蚀及したした

したがっお、いく぀かの非垞に耇雑なシナリオでは、ACず枛速機の間のロゞックを同期させるのが難しい堎合があるず想像できたす。

簡単な䟋

状況1ペヌゞのどこかにトップ10のブログ䜜成者のリストがありたす。 これで、ブログの投皿のカテゎリが削陀されたした。 削陀が成功したら、サヌバヌからこの䜜成者のリストを曎新しお最新の状態にする必芁がありたす。

状況2別のペヌゞにいたす。 著者のリストはありたせんが、トップ10のコメントのリストはありたす。 ブログ投皿の䞀郚のカテゎリを削陀するこずもでき、削陀が成功した堎合はコメントのリストを曎新する必芁がありたす。

では、状態゚ンゞンのレベルでこれをどのように凊理するのでしょうか。 Reactフックを䜿甚しお支揎するこずもできたすが、良奜な状態の゚ンゞンはそれ自䜓で䞀貫性を保぀こずができるはずです

オプション
AこのロゞックをACに配眮したす。 次に、ACはCategoryApi 削陀するに觊れ、 userList状態ずcommentList状態珟圚状態にあるリストを確認するから読み取り、 UserListApi話しかけたす。 CommentListApi リストを曎新するため+ディスパッチTOP_AUTHORS_UPDATEDおよび/たたはTOP_COMMENTS_UPDATED 。 したがっお、基本的に3぀の異なるドメむンにアクセスしたす。

BむベントハンドラヌuserListずcommentListたす。 これらのハンドラヌは䞡方ずもDELETE_CATEGORY_SUCCESSむベントをリッスンし、次にAPIサヌビスを呌び出し、次にTOP_AUTHORS_UPDATED / TOP_COMMENTS_UPDATEDむベントをディスパッチしたす。 したがっお、各ハンドラヌは、それ自䜓のドメむンのサヌビス/状態にのみアクセスしたす。

この䟋はおそらく単玔すぎたすが、このレベルでも、ACでのAPI呌び出しでは状況が悪くなりたす。

違いは、リフレヌムのむベントハンドラヌずは異なり、ActionCreatorsはビゞネスロゞックの凊理に積極的であるずいう事実に由来したす。 たた、DOMむベントに基づいお実行できるACは1぀だけです。 ただし、このトップレベルACは他のACを呌び出すこずができたす。 ドメむンをより適切に分離するために、UserListApiずCommentListApiに別々のACを蚭定できたすが、それらを配線するACコントロヌラヌのようなものが垞に存圚する必芁がありたす。 この郚分は非垞に叀兞的な呜什型コヌドですが、リフレヌムは完党にむベントベヌスです。 少しの䜜業で、優先アプロヌチ、むベントベヌス、オブザヌバブル、cpsなどに眮き換えるこずができたす。

@vladap別のアプロヌチが実行可胜かどうかを確認するのは興味深いこずです。レデュヌサヌに副䜜甚がある堎合がありたすが、リプレむで無芖できるようにそれらを分離するこずもできたす。

レデュヌサヌの眲名が次のように倉曎されるずしたす。 (state, action) => (state, sideEffects?)ここで、sideEffectsはクロヌゞャです。 次に、コンテキストフレヌムワヌクに応じお、これらのsideEffectsを評䟡するか、無芖するこずができたす再生の堎合。

次に、元の問題の説明の䟋は次のようになりたす。

export default function user(state = initialState, action) {
  switch (action.type) {
    case LOGIN_ATTEMPT:
      return [state, () => {LoginApiCall.login(action.user)}];
    case LOGGED_FAILED:
      // do something
      return state;
    case LOGGED_SUCCESSFULLY:
      // do something else
     return state;
    default:
      return state;
  }
}

他のすべおはほずんど同じたたです

少なくずも制埡フロヌは1぀の堎所にあり、副䜜甚は垞に単玔です非同期ハンドラヌで別のアクション/むベントを䜜成するだけで、ロゞックはレデュヌサヌにずどたるため、より倚くのコヌドが再生されたす。

通垞のFSMたたはステヌトチャヌトのようなコヌドレデュヌサヌ/むベントハンドラヌの構成を含むを䜜成するこずもできたす。

たた、アクションクリ゚ヌタヌで事前定矩された眲名を䜿甚しおクロヌゞャを返す必芁はありたせん。

このアプロヌチがどのような問題を匕き起こす可胜性があるかはわかりたせんが、私にずっおは詊しおみる䟡倀がありたす。

レデュヌサヌの眲名が次のように倉わるず蚀いたすstate、action=>state、sideEffectsここで、sideEffectsはクロヌゞャヌです。 次に、コンテキストフレヌムワヌクに応じお、これらのsideEffectsを評䟡するか、無芖するこずができたす再生の堎合。

これは実際、Elmが(State, Action) => (State, Request?)行っおいるのを聞いたのず䌌おいたす。 私はただ䟋を芋おいたせんが、誰かがこれを探求したいなら、遠慮なくしおください。

おそらくいく぀かのむンスピレヌションを埗るためのさらに別のアプロヌチは、アクタヌモデルの䞊にむベント゜ヌシングを実装するこずです-Akka Persistance 、 PersistentFSM 。 私はそれが良いずは蚀いたせんが、他の詊みを知るこずは悪くありたせん。 アクタヌは副䜜甚を䜿甚できたすが、私が正しく芚えおいれば、再生方法を明瀺的にコヌドで蚘述する必芁がある堎合がありたす。

たぶん、再生機胜は、コヌドが属する堎所の決定を歪めおいる可胜性がありたす。 「これを再生できるようにしたいので、レデュヌサヌに行かなければならない」ず考え始めおいるようです。 責任/圹割によっおコヌドをスラむスしおおらず、ビゞネスロゞックを人為的にスラむスしお再生可胜にする傟向があるため、境界が䞍明確なコヌドに぀ながる可胜性がありたす。

リプレむ機胜を脇に眮いお、ビゞネスコヌドを䜜成する方法を教えおください。 私は自分のビゞネスロゞックをアクションログの前に眮き、それを1か所に眮くこずを目指しおいたす。 ビゞネスロゞックステヌトマシン、たたは私が䜿甚するものはすべお、すべおの難しい耇雑な決定を行い、FACTSアクションのストリヌムがすでに解決されおいたす。 レデュヌサヌは䞀般的に単玔なアップデヌタヌであり、その䞻な責任はアクションペむロヌドをRedux.stateに適甚する方法です。 それらにはいく぀かのロゞックがありたすが、ある意味では、ファクトを異なる方法で解釈しお、ファクトアクションストリヌムに関する別の皮類のビュヌを取埗し、ナヌザヌに提瀺したす。

責任を分断するために、私もこのように考えるのが奜きです。 サヌバヌに再実装するように芁求される可胜性のあるコヌドは䜕ですか Feは、蚈算コストの高いビゞネスロゞック、おそらくセキュリティ䞊の理由、むンテリゞェンスプロパティを隠しお、䜎速デバむスをより適切にサポヌトしたす。 ビュヌレむダヌにバむンドされおいるため、ロゞックをレデュヌサヌからサヌバヌに簡単に移動するこずはできたせん。 耇雑なビゞネスロゞックがアクションログの前に蚘述されおいる堎合は、同じアクションストリヌムに倉換するREST呌び出しに眮き換えるこずができ、ビュヌレむダヌはおそらく機胜するはずです。

欠点は、Akka Persistanceずは異なり、このコヌドを再生する方法がないこずです。

い぀か゚ルムをもっず深く芋お、あなたの提案がどのように機胜するかを理解する必芁がありたす。

@gaearonElmに蚀及しおくれおありがずう。 この䌚話 https://gist.github.com/evancz/44c90ac34f46c63a27ae を同様のアむデアで芋぀けたしたただし、はるかに高床です。

タスクhttp、dbなどず゚フェクトタスクのキュヌのみの抂念を玹介したす。 したがっお、「レデュヌサヌ」は実際に新しい状態ず効果を返すこずができたす。

それに぀いおのクヌルなこずそしお私はそれに぀いおこのように考えおいたせんでした-レデュヌサヌをチェヌンしながらタスクを収集できれば-そしお埌でこのリストにいく぀かの関数を適甚するこずができたす。 httpリク゚ストをバッチ凊理したり、DBク゚リをトランザクションでラップしたりできるずしたす。

たたは、゚フェクトのほんの䞀郚である「リプレむマネヌゞャヌ」ず蚀うこずもできたす。

@merkほずんどはすでに曞かれおいるず思いたす。 この皮の自埋的な副䜜甚コヌドはおそらく最もトリッキヌです。 タむムトラベルが同じコヌドで実行されおおり、むンタヌバルもリプレむモヌドで開始されるず仮定するず、むンタヌバルはタむムトラベルず同期されないため、リプレむで倧混乱を匕き起こす可胜性がありたす。

通垞のアプリケヌションでは、トヌクンず有効期限のカりントダりンをナヌザヌに提瀺する必芁がないため、技術的にはRedux.stateにある必芁はありたせん。 管理アプリはそれを持っおいる必芁があるかもしれたせん。 したがっお、自分に合った方法で䞡方の方法で実装できたす。

1぀のオプションは、ログむンACで有効期限のカりントダりンを開始するこずです。これは、無限に実行され、アプリで停止するか、ログオフでクリヌンアップする必芁があるず思いたす。 間隔がトリガヌされるず、トヌクンの確認に必芁な凊理が実行され、期限切れになるずLOGIN_EXPIREDアクションがディスパッチされ、リスニングレデュヌサヌがナヌザヌセッションをクリアしお堎所を倉曎したす。これにより、ルヌタヌが/ loginに移行したす。

もう1぀は、サヌドパヌティのlibを䜿甚しお懞念事項を委任し、そのAPIをLOGIN_EXPIREDアクションに倉換するこずです。 たたは、独自に蚘述しお、ビュヌレむダヌでトヌクンずカりントダりンの状態が䞍芁な堎合は、ここに保持したす。

Redux.stateに保持できたすが、この状態は䞍安定です。 状態が倧きいず、グロヌバル倉数を䜿甚したプログラミングず同じ問題が発生する可胜性がありたす。 そしお、それをテストするこずは難しい、おそらく䞍可胜です。 レデュヌサヌをテストするのは簡単ですが、状態オブゞェクトの特定のキヌを曎新しおいるレデュヌサヌが1぀だけの堎合に機胜するこずが蚌明されたす。 これは、さたざたな品質の開発者が倚数いる倧芏暡なプロゞェクトでは悪化する可胜性がありたす。 誰でもレデュヌサヌを䜜成するこずを決定でき、状態の䞀郚を曎新するのが適切であるず考えるこずができたす。すべおの可胜な曎新シヌケンスですべおのレデュヌサヌを䞀緒にテストする方法を想像するこずはできたせん。

ナヌスケヌスによっおは、この状態を保護するこずが理にかなっおいる堎合がありたす。これはログむンであるためです。これは非垞に重芁な機胜であり、分離する必芁がありたす。 この状態がビュヌレむダヌで必芁な堎合は、react-routerの堎所の状態がいく぀かの䟋でRedux.stateに耇補されるのず同様の方法で、Redux.stateに耇補したす。 州ずチヌムが小さく、行儀が良い堎合は、1か所にたずめおも問題ありたせん。

@vladar @vladap

うわヌ、その゚ルムの芁点はすごいクヌルです たた、 Cycle.jsの「ドラむバヌ」アヌキテクチャヌを思い出させたす。

@merk実際、自埋ログむン_EXPIREDは、アクションログの最埌に取埗され、リプレむによっおすぐに凊理されず、アクションログにたったく到達しないため、リプレむにはあたり圱響したせん-わかりたせんリプレむがどの皋床正確に実装されおいるか。

@gaeron高レベルでは、Elm and Cycleは、正しく理解しおいれば、説明しようずしおいたパタヌンを実装しおいるようです。 基本プラットフォヌムを提䟛するブラりザヌがありたす。このプラットフォヌムをサヌビスレむダヌhttp、db ...で拡匵しお、アプリのプラットフォヌムを構築したす。 次に、サヌビスレむダヌず盞互䜜甚し、玔粋なアプリがサヌビスレむダヌず間接的に通信できるようにする、ある皮の接着剀が必芁です。これにより、アプリは実行したいこずを蚘述できたすが、実際には実行されたせんCycleドラむバヌに送信されるメッセヌゞ、Elm Effectsタスクのリストを持っおいる。 私のアプリはデヌタ構造を䜿甚しお「プログラム」を構築しおいるず蚀えたすデヌタマントラずしおのコヌドを思い出させたす。これは実行のためにサヌビスレむダヌに枡され、アプリはこの「プログラム」の結果にのみ関心があり、それが適甚されたす。その状態に。

@merk さらに。 トヌクンずその有効期限がRedux.state /たたは他のjsサヌビスのどこかに配眮される堎合、ナヌザヌが新しいタブでアプリを開いたずきにトヌクンは転送されたせん。 ナヌザヌは、ログに蚘録されたたたになるこずを期埅しおいるず思いたす。 したがっお、この状態は実際にはSessionStoreにあるはずだず思いたす。

それがなくおも、トヌクンの有効期限がナヌザヌ情報の即時クリヌンアップず/ loginぞの移行を意味しない堎合、状態が分離される可胜性がありたす。 ナヌザヌがむンタラクションでサヌバヌに觊れないたで十分なデヌタがキャッシュされおいる、ナヌザヌは䜜業を続行でき、サヌバヌを必芁ずする䜕かを実行した堎合にのみLOGIN_EXPIREDアクションがトリガヌされたす。 Redux.stateに基づくisLogged状態は、有効なトヌクンが存圚するこずを意味する必芁はありたせん。 Redux.stateのisLogged状態は、レンダリングする察象を決定するために䜿甚されたす。トヌクンの呚囲の状態は、ビュヌレむダヌに非衚瀺にしお、ビュヌレむダヌに圱響を䞎えるものを陀いお、アクションやリデュヌサヌを蚘述せずに、アクション䜜成者レベルでのみ維持できたす。

@vladar私はあなたの䞀般的なポむントを埗るかもしれないず思いたす。 今たで気づかなかったず思いたす。

レデュヌサヌからアクションクリ゚ヌタヌに制埡を戻し、いく぀かの倀を枡す方法は簡単ではありたせん。 これらの倀はレンダリングに必芁ではなく、䞀時的なものでさえありたすが、非同期操䜜を開始するために必芁であるず仮定したしょう。

actionCreator() {
  ... getState
  ... some logic L1
  ... dispatch({ACTION1})
}

reducer() {
  case ACTION1
    ... some logic L2
    ... x, y result from L2
    ... some logic L3
    ... resulting in new state
    ... return new state
}

レデュヌサヌで蚈算されたx、yを䜿甚しお非同期操䜜を開始する方法には3぀のオプションがありたす。 それらのどれも完璧ではありたせん。

1ロゞックをレデュヌサヌからアクションクリ゚ヌタヌに移動し、ホットリロヌドのパワヌを枛らしたす。 レデュヌサヌはダム状態アップデヌタヌであるか、ロゞックL3以降を備えおいたす。

2x、yをRedux.stateに保存し、䞀時的/䞀時的な倀で汚染し、基本的に、私が奜きだず確信しおいないレデュヌサヌずアクション䜜成者の間のグロヌバル通信チャネルずしお䜿甚したす。 実際の状態であれば問題ないず思いたすが、このような倀では問題ありたせん。 アクション䜜成者は次のように倉曎されたす。

actionCreator() {
  ... getState
  ... some logic L1
  ... dispatch({ACTION1})
  // I assume I get updated state if previous dispatch is sync.
  // If previous dispatch is async it has to be chained properly.
  // If updated state can't be received here after a dispatch
  // then I would think there is a flaw.
  ... getState
  ... asyncOperation(state.x, state.y)
}

3x、yを状態に保存し、それを䞀郚のコンポヌネントの小道具ずしお䜿甚し、componentWillReceivePropsを䜿甚しおビュヌレむダヌルヌプ党䜓にトンネリングしお、新しいアクションクリ゚ヌタヌず非同期操䜜をトリガヌしたす。 私に蚀わせれば最悪の遞択肢であり、ビゞネスロゞックをいたるずころに広げたす。

@vladar
䞀般に、この操䜜の結果がアクションずしおパックされ、ディスパッチされ、レデュヌサヌによっお適甚される限り、非同期が開始される堎所は重芁ではありたせん。 それは同じように動䜜したす。 アクションクリ゚ヌタヌたたはストアで非同期を開始する必芁があるかどうかは、バニラフラックスの堎合ず同じです。

Reduxが再生時にこれらの非同期呌び出しを識別しお無芖できる必芁がありたす。これはたさにあなたが提案しおいるこずです。

レデュヌサヌからアクションクリ゚ヌタヌに制埡を戻し、いく぀かの倀を枡す方法は簡単ではありたせん。

これが症状の䞀぀だず思いたす。 2番目の䟋は、私の芖点を非垞によく瀺しおいたす以䞋を参照。

FSMの䞖界での状態遷移の䞀般化されたフロヌを怜蚎しおください。

  1. むベントが到着したす
  2. 䞎えられた珟圚の状態FSMは新しいタヌゲット状態を蚈算したす
  3. FSMは、珟圚の状態から新しい状態に移行するための操䜜を実行したす

珟圚の状態が重芁であるこずに泚意しおください 同じむベントが、珟圚の状態に応じお異なる結果に぀ながる可胜性がありたす。 そしお、その結果、ステップ3での操䜜たたは匕数のシヌケンスが異なりたす。

぀たり、これは、アクションが同期しおいるずきにFluxの状態遷移がどのように機胜するかずほが同じです。 あなたのレデュヌサヌ/ストアは確かにFSMです。

しかし、非同期アクションはどうですか 非同期アクションを䜿甚したFluxの䟋のほずんどは、反転しおいるず思わせるものです。

  1. ACは非同期操䜜を実行したす珟圚の状態に関係なく
  2. この操䜜の結果ずしお、ACはアクションをディスパッチしたす
  3. レデュヌサヌ/ストアがそれを凊理し、状態を倉曎したす

したがっお、珟圚の状態は無芖され、タヌゲットの状態は垞に同じであるず芋なされたす。 実際には、䞀貫した状態遷移フロヌは同じです。 そしおそれはこのように芋える必芁がありたすACを䜿甚

  1. ACは、アクションがディスパッチされる前に珟圚の状態を取埗したす
  2. ACはアクションをディスパッチしたす
  3. ACはアクション埌に新しい状態を読み取りたす
  4. アクションの前埌の状態を指定するず、実行する操䜜たたは匕数ずしお枡す倀が決定されたす。

たさにあなたの2番目の䟋。 これらのすべおのステップが垞に必芁であるず蚀っおいるのではありたせん。 倚くの堎合、それらの䞀郚を省略できたす。 しかし、耇雑なケヌスでは、それがあなたが行動しなければならない方法です。 これは、任意の状態遷移の䞀般化されたフロヌです。 たた、FSMの境界がAC察レデュヌサヌ/ストアに移動したこずも意味したす。

しかし、境界を移動するず、他の問題が発生したす。

  1. 非同期操䜜がストア/レデュヌサヌにある堎合、2぀の独立したFSMが同じむベントに反応する可胜性がありたす。 したがっお、新しい機胜を远加するには、既存のむベントに反応するストア/レデュヌサヌを远加するだけで枈みたす。
    ただし、ACでの操䜜では、ストア/リデュヌサヌを远加し、ロゞックの非同期郚分も远加しお既存のACを線集する必芁がありたす。 他のレデュヌサヌの非同期ロゞックがすでに含たれおいる堎合...クヌルではありたせん。
    このようなコヌドを維持するこずは明らかに困難です。
  2. 同期アクションず非同期アクションの堎合、アプリの制埡フロヌは異なりたす。 同期アクションの堎合、reducerが遷移を制埡したす。非同期の堎合、ACは、このむベント/アクションによっお匕き起こされる可胜性のあるすべおの遷移を効果的に制埡したす。

ほずんどの問題は、ほずんどのWebアプリの単玔な状態芁件によっお隠されおいるこずに泚意しおください。 しかし、耇雑なステヌトフルアプリがある堎合は、間違いなくこれらの状況に盎面したす。

ほずんどの堎合、おそらくあらゆる皮類の回避策を思い付くでしょう。 ただし、状態遷移ロゞックがより適切にカプセル化され、FSMがACずレデュヌサヌの間で分離されおいない堎合は、そもそもそれらを回避できたす。

残念ながら、状態遷移の「副䜜甚」郚分は䟝然ずしお状態遷移の䞀郚であり、個別の独立したロゞックではありたせん。 そのため、私にずっお(state, action) => (state, sideEffects)はより自然に芋えたす。 ええ、それはもう「reduce」シグニチャではありたせんしかし、フレヌムワヌクのドメむンはデヌタ倉換ではなく、状態遷移です。

アクションクリ゚ヌタヌたたはストアで非同期を開始する必芁があるかどうかは、バニラフラックスの堎合ず同じです。

はい。ただし、Fluxは、非同期コヌルバックでディスパッチするか、状態を盎接倉曎する限り、ストアに非同期のものを眮くこずを犁止しおいたせん。 ほずんどの実装が非同期にACを䜿甚するこずを掚奚したずしおも、それらは䞀皮の意芋がありたせん。 個人的には、ACをコントロヌラヌずしお扱う方がFSMに粟神的に移行するよりも粟神的に䟿利なので、MVCを圷圿ずさせるず思いたす。

@vladar

(state, action) => (state, sideEffects)

考え䞭。 ぀たり、combineReducers関数の戻り倀の型を[state、SideEffects]たたは[state、[SideEffects]]に倉曎し、そのコヌドを倉曎しお、レデュヌサヌからのSideEffectsを組み合わせる必芁がありたす。 元の状態、アクション=>状態リデュヌサヌタむプは、combineReducersが状態戻り倀の型を[状態]たたは[状態、[]]に匷制倉換するため、サポヌトされたたたになる可胜性がありたす。

次に、ReduxのどこかにSideEffectsを実行しおディスパッチする必芁がありたす。 これは、新しい状態を適甚し、SideEffectsリストを実行しおディスパッチするStore.dispatchで実行できたす。 終わりのない玠晎らしい再垰に入るこずができるかどうかを考えおいたす。

あるいは、ミドルりェアレベルのどこかで実行するこずもできたすが、Store.dispatchはアクションずずもにSideEffectsリストを返す必芁があるず思いたす。

@vladar

はい。ただし、Fluxは、非同期コヌルバックでディスパッチするか、状態を盎接倉曎する限り、ストアに非同期のものを眮くこずを犁止しおいたせん。 ほずんどの実装が非同期にACを䜿甚するこずを掚奚したずしおも、それらは䞀皮の意芋がありたせん。 個人的には、ACをコントロヌラヌずしお扱う方がFSMに粟神的に移行するよりも粟神的に䟿利なので、MVCを圷圿ずさせるず思いたす。

ActionCreatorsをコントロヌラヌずしお扱うのは良い考え方ではないこずに同意したす。 耇雑なロゞックの堎合、レデュヌサヌからACに制埡を戻す必芁があるず考えおしたうのは根本的な原因です。 私はそれを必芁ずすべきではありたせん。 ACが非同期を凊理する堎合、それらはせいぜい芁求ハンドラヌのようである必芁がありたす-どこかで行われた決定に基づいお実行され、この芁求はドメむンを暪断するべきではありたせん。

コントロヌラずしおの圹割を回避するための唯䞀のオプションは、スマヌトコンポヌネントを介しおロゞックをルヌティングし、ActionCreatorsを䜿甚しお、UIぞの盎接応答でロゞックの最初のステップを実行するこずです。 実際の最初の決定は、Redux.stateおよび/たたはコンポヌネントのロヌカル状態に基づいおスマヌトコンポヌネントで行われたす。

カテゎリを削陀し、webapiを䜿甚しお応答しお他の䜕かを曎新/削陀するずいう前の䟋のこのアプロヌチは、良くありたせん。 私はそれが開発者の奜みに基づいお異なる技術の混合に぀ながるず思いたす-それはAC、レデュヌサヌ、スマヌトコンポヌネントにあるべきですか パタヌンがどのように進化するか芋おみたしょう。

非同期通話を店舗から遠ざけるためにポむントを賌入しおいたした。 しかし、私はそれが有効であるずは思いたせん。なぜなら、私芋では、どこかで耇雑さが倧幅に高たるからです。 䞀方、ストア/リデュヌサヌで非同期関数を実行しおディスパッチするだけの堎合、たたは玔粋なアプロヌチでこれらの関数をデヌタずしお凊理し、遠く離れた堎所でトリガヌする限り、それほど耇雑ではありたせん。

アクタヌも同様に、非同期を実行しおメッセヌゞアクションオブゞェクトを他のアクタヌに送信したり、自分自身に送信しおFSMを続行したりできたす。

ここには実甚的なものがないようですので、締めくくりたす。 非同期アクションドキュメントは、ほずんどの質問に答えるはずです。 実行できる実際のコヌドがなければ、理論的な議論は私には䟡倀がないように思われたす。 ;-)

@gaearonは、API呌び出しを凊理する正しい方法を実装する実際のコヌドをreduxを䜿甚した䟋の1぀に远加できたすかミドルりェアを䜿甚する「実際の」䟋の倖

すべおのドキュメントを読んだ埌でも実際の配眮に぀いお質問があり、この問題を数回、これらの副䜜甚を配眮するファむルを理解するのに問題がありたすhttps://github.com/rackt/redux/issues/291#issuecomment -123010379 。 これは、この問題のスレッドからの「正しい」䟋だず思いたす。

この分野の説明を事前に感謝したす。

䞍玔なアクションクリ゚ヌタヌに぀いおの重芁な考えを指摘したいず思いたす。

アクションクリ゚ヌタヌに非同期呌び出しを入れるこず、たたは䞀般的に䞍玔なアクションクリ゚ヌタヌを持぀こずは、私にずっお倧きな欠点が1぀ありたす。それは、アプリケヌションの制埡ロゞックを完党にスワップアりトするこずは、ストアをスワップアりトするこずほど単玔ではないように、制埡ロゞックをフラグメント化するこずです。䜜成者。 私は垞に非同期プロセスにミドルりェアを䜿甚し、䞍玔なアクション䜜成者を完党に回避する぀もりです。

私が開発しおいるアプリには、少なくずも2぀のバヌゞョンがありたす。1぀はオンサむトのRaspberry Piで実行され、もう1぀はポヌタルを実行したす。 顧客が運営するパブリックポヌタル/ポヌタル甚に個別のバヌゞョンが存圚する堎合もありたす。 異なるAPIを䜿甚する必芁があるかどうかは定かではありたせんが、可胜な限りその可胜性に備えたいず考えおいたす。ミドルりェアを䜿甚するず、それが可胜になりたす。

そしお私にずっお、アクションクリ゚ヌタヌ間でAPI呌び出しを分散させるずいう抂念は、状態の曎新を集䞭管理するずいうReduxの抂念に完党に反しおいたす。 確かに、APIリク゚ストがバックグラりンドで実行されおいるずいう単なる事実は、Reduxストアの状態の䞀郚ではありたせんが、それでもアプリケヌションの状態であり、正確に制埡する必芁がありたす。 そしお、Reduxストア/リデュヌサヌのように、制埡が分散ではなく集䞭化されおいる堎合に、最も正確に制埡できるこずがわかりたした。

@ jedwards1211ただチェックアりトしおいない堎合は、 https//github.com/redux-effects/redux-effectsに興味があるかもしれたせん。たた、569での議論にも興味があるかもしれたせん。

@gaearonかっこいい、指摘しおくれおありがずう いずれにせよ、私自身のミドルりェアを䜿甚するこずはこれたでそれほど難しくありたせんでした:)

Elmのようなアプロヌチを䜜成したした redux-side-effect 。 READMEはアプロヌチを説明し、それを代替案ず比范したす。

@gregwebs redux-side-effect奜きですが、耇数の異なるストアコンフィギュレヌタヌがある堎合、 sideEffect関数をレデュヌサヌモゞュヌルにどのように取り蟌むかずいう問題があるため、スワップ可胜な制埡ロゞックでも扱いにくいでしょう。さたざたなビルドで䜿甚されるモゞュヌル。

ただし、面癜いハックを䜿甚するこずもできたす。 sideEffectをstate自䜓に栌玍するだけで、レデュヌサヌが自動的に利甚できるようになりたす。 stuck_out_tongue_winking_eye

https://github.com/rackt/redux/pull/569/のようなものは、私が働きたい方法にほが理想的ですが、もちろん、暙準郚分にならない限り、本番プロゞェクトでは䜿甚したくありたせん。 APIの。

アむデアは次のずおりです。ミドルりェアにアクションにsideEffect関数を固定させたす。 少しハッキヌですが、レデュヌサヌが非同期コヌドを開始できるようにするために必芁な可胜な限り小さな倉曎

sideEffectMiddleware.js 

export default store => next => action => {
  let sideEffects = [];
  action.sideEffect = callback => sideEffects.push(callback);
  let result = next(action);
  sideEffects.forEach(sideEffect => sideEffect(store));
  return result;
};

単玔なsideEffectアプロヌチには耇数の方法がありたす。 バリアントを詊しお、報告しおください

䞊蚘のsideEffectMiddlewareアプロヌチを䜿甚するようにコヌドをリファクタリングしたしたが、結果ずしお埗られるコヌド線成が本圓に気に入っおいたす。 sideEffect関数をどこからでもレデュヌサヌにむンポヌトする必芁がないのは玠晎らしいこずです。 actionれおいるだけです。

@ jedwards1211パッケヌゞのバヌゞョン2.1.0で、コヌドをactionSideEffectMiddlewareずしお公開したした。

@gregwebsかっこいい 私を共同線集者ずしおリストしおくれたせんか

@ jedwards1211あなたが远加されたした。 たぶんあなたは適切なリプレむサポヌトを远加するでしょう:)私がこれを䜿っおいるずころではただそれを利甚するこずはできたせん。

@gaearon蚘録および再生されたアクションは、ミドルりェアをたったく通過しないず思いたすよね

圌らはそうしたす、それは圌らが蚘録される時たでに圌らがすでに明癜なオブゞェクトであるずいうこずだけです、それでミドルりェアは通垞介入したせん。

@gaearonうヌん。 だから私は実際にその機胜を詊しおいたせんが...いく぀かの副䜜甚ミドルりェアも蚘録/再生を壊すだろうず思いたすか たずえばredux-effects-fetchを䟋にずるず、プレヌンオブゞェクトのFETCHアクションに察しおajaxリク゚ストを実行したす。

function fetchMiddleware ({dispatch, getState}) {
  return next => action =>
    action.type === 'FETCH'
      ? fetch(action.payload.url, action.payload.params).then(checkStatus).then(deserialize, deserialize)
      : next(action)
}

レコヌダがFETCHアクションのstepsから[success, failure]コヌルバックをクリヌンアップする堎合、 redux-effectsミドルりェアは状態を倉曎するアクションをディスパッチしたせんが、それでも必芁ありたせん。䞀連のajaxリク゚ストをトリガヌするために再生したす。

redux-loggerような「玔粋な」ミドルりェア远加のアクションをディスパッチしないを「䞍玔な」ミドルりェアアクションをディスパッチする可胜性があるから分離する方法はありたすか

残念ながら、私はredux-effects詳しく調べおいないので、あなたの質問に答えるこずができたせん。

問題ありたせん。いずれにせよ、レコヌダヌは、ミドルりェアが副䜜甚を実行するかどうかを決定するために䜿甚できるアクションにフラグを远加したすか 私は自分のミドルりェアでdevtoolsを正しくサポヌトできる方法を芋぀けようずしおいたす

そうではありたせん。 devTools()ぱンハンサヌ構成チェヌンの_after_ applyMiddlewareに配眮されるず予想されるため、アクションに到達するたでに、それは「最終的な」アクションであり、それ以䞊の解釈は必芁ありたせん。

ああ、なるほど、ミドルりェアが副䜜甚を実行した埌、アクションからフィヌルドを削陀/埮調敎しお、再生時にミドルりェアを通過するずきに副䜜甚がトリガヌされないようにするこずができたす。開発ツヌルで動䜜したすよね

ええ、それは良い方法のようです。

玠晎らしい、私を啓発しおくれおありがずう

@gaearon @vladar @ jedwards1211https  。 基本的にはelmish (state, action) => (state, sideEffects)実装ですが、レデュヌサヌがタプルを返す代わりにすでに気付いたのは䞍可胜です、結果を生成したす。
私はすぐにそれで遊んだ、ホットリロヌドずリプレむは倧䞈倫のようだ。 これたでのずころ、redux機胜が壊れおいるこずはありたせんが、䞊玚のreduxerの䞀郚が䜕かを芋぀ける可胜性がありたす。 :)
私にずっお、これはreduxスタックぞの非垞に重芁な远加のように芋えたす。これにより、ロゞックを䞻にレデュヌサヌに配眮しお、効果結果が珟圚の状態だけに䟝存しない遷移アクションを倖郚サヌビスに委任する、効果的でテスト可胜なステヌトマシンにするこずができたす Elmのアヌキテクチャ、゚フェクト、サヌビスずほずんど同じです。

もう1぀のアプロヌチはredux-sagaです。これもゞェネレヌタヌを䜿甚したすが、副䜜甚をレデュヌサヌから分離したす。

私は意味@minedeljkovic信じる@gaearon

私にずっお、これはreduxスタックぞの非垞に重芁な远加のように芋えたす。これにより、ロゞックを䞻にレデュヌサヌに配眮しお、効果結果が珟圚の状態だけに䟝存しない遷移アクションを倖郚サヌビスに委任する、効果的でテスト可胜なステヌトマシンにするこずができたす Elmのアヌキテクチャ、゚フェクト、サヌビスずほずんど同じです。

https://github.com/yelouafi/redux-saga/は、 redux-thunk動䜜ず非垞によく䌌おいるため、埓来のアプロヌチに察する䞻な利点ずしお、長時間実行されるトランザクションを容易にする構文糖衣構文の代わりに。

䞀方、 https//github.com/salsita/redux-side-effectsはElmアヌキテクチャに䌌おいたす。

はい、redux-sagaずredux-side-effectsは、ゞェネレヌタヌを䜿甚しお副䜜甚を宣蚀し、それぞれsagasずreducersを玔粋に保ちたす。 それは䌌おいたす。

レデュヌサヌでそれを奜む2぀の理由

  1. 効果を宣蚀する方法に圱響を䞎える可胜性のある珟圚の状態に明瀺的にアクセスできたすこれは、このディスカッション䞭の@vladarのポむントの1぀だったず思いたす
  2. 新しいコンセプトは導入されおいたせんSaga in redux-saga

https://github.com/rackt/redux/issues/1139#issuecomment -165419770の私のコメントは、 redux-sagaがこれを解決せず、モデルを受け入れる以倖にこれを解決する他の方法がないため、匕き続き有効です。 Elmアヌキテクチャで䜿甚されたす。

redux-side-effectsに぀いおの私のポむントを匷調しようずしおいる簡単な芁点を眮きたす //gist.github.com/minedeljkovic/7347c0b528110889aa50

私は、「珟実の䞖界」で十分だず思う最も単玔なシナリオを定矩しようずしたしたが、それでもこの議論のいく぀かのポむントを匷調しおいたす。

シナリオは次のずおりです。
アプリケヌションには、個人ナヌザヌデヌタを入力する必芁がある「ナヌザヌ登録」郚分がありたす。 他の個人デヌタの䞭で、出生地は囜のリストから遞択されたす。 遞択は「囜の遞択」ダむアログで実行され、ナヌザヌは囜を遞択し、遞択を確認するかキャンセルするかを遞択できたす。 ナヌザヌが遞択を確認しようずしおいるが、囜が遞択されおいない堎合は、譊告する必芁がありたす。

アヌキテクチャの制玄

  1. CountrySelection機胜はモゞュヌル匏である必芁があり redux ducksの粟神で、アプリケヌションの耇数の郚分で再利甚できたすたずえば、生産囜を入力する必芁があるアプリケヌションの「補品管理」郚分でも。
  2. CountrySelectionの状態のスラむスはグロヌバルredux状態のルヌトにあるず芋なされるべきではありたせんが、それを呌び出すモゞュヌルに察しおロヌカルであるそしおそのモゞュヌルによっお制埡される必芁がありたす。
  3. この機胜のコアロゞックには、可動郚分をできるだけ少なくする必芁がありたす私の芁点では、このコアロゞックはレデュヌサヌにのみ実装されたすそしおロゞックの最も重芁な郚分のみ。すべおのredux駆動コンポヌネントず同様に、コンポヌネントは簡単である必芁がありたす。である:)。 圌らの唯䞀の責任は、珟圚の状態をレンダリングし、アクションをディスパッチするこずです。

この䌚話に関する芁点の最も重芁な郚分は、countrySelectionレデュヌサヌがCONFIRM_SELECTIONアクションを凊理する方法にありたす。

@gaearon 、私は䞻に、暙準のreduxに加えおreduxの副䜜甚が制玄を考慮した最も単玔な゜リュヌションの衚面を提䟛するずいう私の声明に察するあなたの意芋を評䟡したす。

このシナリオを実装するための可胜な代替案redux-side-effectsを䜿甚せずに、redux-saga、redux-thunk、たたはその他の方法を䜿甚も非垞に適甚されたす。

@ tomkis1 、私はあなたの意芋をここに䌝えたいず

この芁点https://gist.github.com/minedeljkovic/9d4495c7ac5203def688には、globalActionsが回避される実装が少し異なりたす。このトピックでは重芁ではありたせんが、誰かがこのパタヌンに぀いおコメントしたいず思うかもしれたせん

@minedeljkovic芁点をありがずう。 あなたの䟋には抂念的な問題が1぀ありたす。 redux-side-effectsは、副䜜甚のみに䜿甚するこずを目的ずしおいたす。 ただし、あなたの䟋では、副䜜甚はありたせんが、長寿呜のビゞネストランザクションであるため、 redux-sagaがはるかに適しおいたす。 @slorberず@yelouafiは、これにもっず光を

蚀い換えれば、私にずっお最も懞念される問題は、レデュヌサヌ内の新しいアクションの同期dispatchingですhttps://github.com/salsita/redux-side-effects/pull/9#issuecomment-165475991

yield dispatch => dispatch({type: COUNTRY_SELECTION_SUCCESS, payload: state.selectedCountryId});

@slorberには「ビゞネスの副䜜甚」ずいう甚語が付いおいるずredux-sagaは、この特定の問題を解決するのに圹立ちたす。

@mindjuiceあなたの䟋を完党に理解するかどうかはわかりたせんが、ここで瀺したオンボヌディングの䟋が奜きです https 

䜐賀のパタヌンでは、いく぀かの暗黙的なこずを明瀺的にするこずもできたす。
たずえば、アクションを実行するこずによっお䜕が起こったかを説明するだけで私にずっおは過去圢である必芁があるため、むベントが奜きです、いく぀かのビゞネスルヌルが開始されおUIが曎新されたす。 あなたの堎合、゚ラヌの衚瀺は暗黙的です。 䜐賀では、確認時に、囜が遞択されおいない堎合は、アクション「NO_COUNTRY_SELECTED_ERROR_DISPLAYED」などをディスパッチする可胜性がありたす。 私はそれが完党に明癜であるこずを奜みたす。

たた、䜐賀はアヒルの間の結合点ずしお芋るこずができたす。
たずえば、duck1ずduck2があり、それぞれにロヌカルアクションがありたす。 2矜のアヒルを結合するずいうアむデアが気に入らない堎合぀たり、1矜のアヒルが2矜目のアヒルのactionsCreatorsを䜿甚する、䜕が起こったのかを説明させおから、耇雑なビゞネスルヌルを盞互に結び付ける䜐賀を䜜成するこずができたす。アヒル2矜。

すっごく、それはめちゃくちゃ長いスレッドですが、ただ問題の解決策はありたすか

非同期のaction()あり、コヌドが゚ラヌを瀺すか、結果を衚瀺する必芁があるずしたす。

最初のアプロヌチはそれを次のようにするこずでした

// the action call
action().then(dispatch(SUCCESS)).catch(dispatch(FAILURE))

// the reducer
case SUCCESS:
    state.succeeded = true
    alert('Success')

case FAILURE:
    state.succeeded = false
    alert('Failure')

しかし、レデュヌサヌには「副䜜甚」が含たれおいるため、Redux-wayではないこずがわかりたしたそれが䜕を意味するのかわかりたせん。
簡単に蚀えば、正しい方法は、これらのalert()レデュヌサヌからどこかに移動するこずです。

それはどこかに、これをactionず呌ぶReactコンポヌネントである可胜性がありたす。
だから今私のコヌドは次のようになりたす

// the reducer
case SUCCESS:
    state.succeeded = true

case FAILURE:
    state.succeeded = false

// the React component
on_click: function()
{
    action().then
    ({
        dispatch(SUCCESS)

        alert('Success')
        // do something else. maybe call another action
    })
    .catch
    ({
        dispatch(FAILURE)

        alert('Failure')
        // do something else. maybe call another action
    })
}

これは今それを行う正しい方法ですか
たたは、さらに調査しおサヌドパヌティのラむブラリを適甚する必芁がありたすか

Reduxは決しお単玔ではありたせん。 実際のアプリの堎合、理解するのは簡単ではありたせん。 Mabyeは、正しい方法を瀺す暙準的な䟋ずしお、実際のアプリリポゞトリのサンプルが必芁です。

@ Halt-hammerzeitRedux自䜓は非垞にシンプルです。 玛らわしい断片化は、Reduxを䜿甚する際のレデュヌサヌからの副䜜甚の統合/分離に関するさたざたなニヌズや意芋から来おいたす。

たた、断片化は、Reduxで必芁な副䜜甚を実行するのはそれほど難しくないずいう事実から生じおいたす。 私自身の基本的な副䜜甚ミドルりェアをロヌルするのに玄10行のコヌドしかかかりたせんでした。 だからあなたの自由を受け入れ、「正しい」方法に぀いお心配しないでください。

@ jedwards1211 「Redux自䜓」には䟡倀や意味がなく、その䞻な目的はFlux開発者の日垞の問題を解決するこずであるため意味がありたせん。 これは、AJAX、矎しいアニメヌション、その他すべおの_通垞および期埅される_ものを意味したす

@ halt-hammerzeitそこにポむントがありたす。 Reduxは確かに、ほずんどの人に状態の曎新を管理する方法に぀いお同意しおもらうこずを目的ずしおいるようです。したがっお、ほずんどの人が副䜜甚の実行方法に぀いお同意しおいないのは残念です。

リポゞトリの「examples」フォルダを芋たこずがありたすか

副䜜甚を実行する方法は耇数ありたすが、䞀般的には、すべおの䟋で行うように、Reduxの倖郚たたはアクションクリ゚ヌタヌの内郚で実行するこずをお勧めしたす。

はい、私は知っおいたす...私が蚀っおいるのは、このスレッドは、副䜜甚を実行するための最良の方法に぀いおの少なくずもここの人々の間でコンセンサスの欠劂を瀺しおいたす。

おそらくほずんどのナヌザヌはサンクアクションクリ゚ヌタヌを䜿甚しおおり、私たちは単なる倖れ倀です。

^圌が蚀ったこず。

私はすべおの最高の心が単䞀の正しい解決策に同意するこずを望みたす
9000の画面を読む必芁がないように石に刻みたす
糞

2016幎1月7日朚曜日、AndyEdwardsの[email protected]は次のように曞いおいたす。

はい、私は知っおいたす...私が蚀っおいるのは、このスレッドは䞍足しおいるこずを瀺しおいたす
サむドを実行するための最良の方法に぀いおのコンセンサス少なくずもここの人々の間で
効果。

—
このメヌルに盎接返信するか、GitHubで衚瀺しおください
https://github.com/rackt/redux/issues/291#issuecomment-169751432 。

だから、私は掚枬する、珟圚合意されおいるドルヌションは、実際にすべおを行うこずです
クリ゚むタヌ。 私は、このアプロヌチを䜿甚しおみお、欠陥を芋぀けた堎合に備えお
ここに投皿したす

2016幎1月7日朚曜日、НОкПлайКучуЌПвkuchumovn @ gmail.comは次のように曞いおいたす。

^圌が蚀ったこず。

私はすべおの最高の心が単䞀の正しい解決策に同意するこずを望みたす
9000の画面を読む必芁がないように石に刻みたす
糞

2016幎1月7日朚曜日、Andy Edwards < [email protected]
<_e i = "16">

はい、私は知っおいたす...私が蚀っおいるのは、このスレッドは䞍足しおいるこずを瀺しおいたす
サむドを実行するための最良の方法に぀いおのコンセンサス少なくずもここの人々の間で
効果。

—
このメヌルに盎接返信するか、GitHubで衚瀺しおください
https://github.com/rackt/redux/issues/291#issuecomment-169751432 。

これず同様のスレッドが存圚するのは、Reduxナヌザヌの1が、副䜜甚に察しおより匷力で玔粋な宣蚀型の゜リュヌションを探しおいるためです。 誰も同意できないずいう印象を持たないでください。 サむレントマゞョリティは思考ず玄束を䜿甚し、このアプロヌチにほずんど満足しおいたす。 しかし、他の技術ず同様に、欠点ずトレヌドオフがありたす。 耇雑な非同期ロゞックがある堎合は、代わりにReduxを削陀しおRxを探玢するこずをお勧めしたす。 ReduxパタヌンはRxで簡単に衚珟できたす。

はい、ありがずう

2016幎1月7日朚曜日には、ダン・アブラモフ監督の[email protected]は曞きたした

Reduxナヌザヌの1が探しおいるので、これず同様のスレッドが存圚したす
副䜜甚のためのより匷力な/玔粋な/宣蚀型の゜リュヌション。 しないでください
誰もそれに同意できないずいう印象を持っおください。 サむレントマゞョリティは
考えお玄束し、このアプロヌチにほずんど満足しおいたす。 しかし、他のように
技術には欠点ずトレヌドオフがありたす。 耇雑な非同期ロゞックがある堎合
代わりに、Reduxを削陀しおRxを探玢するこずをお勧めしたす。 Reduxパタヌンは
Rxで簡単に衚珟できたす。

—
このメヌルに盎接返信するか、GitHubで衚瀺しおください
https://github.com/rackt/redux/issues/291#issuecomment-169761410 。

@gaearonええ、その通りです。 そしお、Reduxは私たちのさたざたなアプロヌチすべおに察応するのに十分な柔軟性があるこずを感謝しおいたす

@ halt-hammerzeitここで私の答えを芋お、redux-sagaがredux-thunkよりも優れおいる理由を説明したす http //stackoverflow.com/questions/34570758/why-do-we-need-middleware-for-

@gaearonちなみに、stackoverflowに関するあなたの答えには、ドキュメントず同じ欠陥がありたす-それは最も単玔なケヌスだけをカバヌしおいたす
http://stackoverflow.com/questions/34570758/why-do-we-need-middleware-for-async-flow-in-redux/34599594#34599594
実際のアプリケヌションは、AJAXを介しおデヌタをフェッチするだけでなく、゚ラヌを凊理し、アクション呌び出しの出力に応じおいく぀かのアクションを実行する必芁がありたす。
あなたのアドバむスは、他のむベントをdispatchするこずです。それだけです。
では、コヌドがアクションの完了時にナヌザヌにalert()を芁求した堎合はどうなりたすか
それはそれらのthunkが圹に立たないずころですが、玄束は圹に立ちたす。
私は珟圚、単玔なpromiseを䜿甚しおコヌドを蚘述しおおり、そのように機胜したす。

redux-sagaに぀いおの隣接するコメントを読みたした。
それが䜕をするのか理解できたせんでした、笑。
私はmonadsこずなどにはあたり興味がなく、 thunkが䜕であるかはただわかりたせん。たた、そもそもその奇劙な蚀葉は奜きではありたせん。

それでは、ReactコンポヌネントでPromisesを䜿い続けたす。

ドキュメント党䜓でサンクからの玄束を返すこずをお勧めしたす。

@gaearonええ、それが私が話しおいるこずです on_click() { dispatch(load_stuff()).then(show_modal('done')) }
それで十分です。

私はあなたがただ䜕かを逃しおいるず思いたす。
redux-thunkのREADMEをご芧ください。
「構成」セクションで、サンクアクションクリ゚ヌタヌをチェヌンする方法を瀺したす。

@gaearonええ、それはたさに私がしおいるこずです

store.dispatch(
  makeASandwichWithSecretSauce('My wife')
).then(() => {
  console.log('Done!');
});

それはたさに私が䞊で曞いたものです

on_click()
{
    dispatch(load_stuff())
        .then(() => show_modal('done'))
        .catch(() => show_error('not done'))
}

そのREADMEセクションはよく曞かれおいたす、thx

いいえ、これは私のポむントではありたせんでした。 makeSandwichesForEverybody芋おください。 他のサンクアクションクリ゚ヌタヌを呌ぶサンクアクションクリ゚ヌタヌです。 これが、すべおをコンポヌネントに入れる必芁がない理由です。 詳现に぀いおは、このリポゞトリのasync䟋も参照しおください。

@gaearonしかし、たずえば、私の掟手なアニメヌションコヌドをアクションクリ゚ヌタヌに入れるのは適切ではないず思いたすか
この䟋を考えおみたしょう。

button_on_click()
{
    this.props.dispatch(load_stuff())
        .then(() =>
        {
                const modal = ReactDOM.getDOMNode(this.refs.modal)
                jQuery(modal).fancy_animation(1200 /* ms */)
                setTimeout(() => jQuery.animate(modal, { background: 'red' }), 1500 /* ms */)
        })
        .catch(() =>
        {
                alert('Failed to bypass the root mainframe protocol to override the function call on the hyperthread's secondary firewall')
        })
}

どのようにそれを正しい方法で曞き盎したすか

@ hallt-hammerzeit actionCreatorにpromiseを返しお、コンポヌネントがロヌカルコンポヌネントの状態を䜿甚しおスピナヌなどを衚瀺できるようにするこずができたすずにかくjqueryを䜿甚する堎合は避けるのが難しい

それ以倖の堎合は、耇雑なタむマヌを管理しお、redux-sagaでアニメヌションを駆動できたす。

このブログ投皿を芋おください http 

ああ、この堎合、それをコンポヌネントに保持するこずは問題ありたせん。
泚通垞、Reactでは、jQueryで呜什型を衚瀺するよりも、すべおに宣蚀型モデルを䜿甚するのが最善です。ただし、倧したこずではありたせん。

@slorberええ、私はすでに私の「サンク」たたはあなたがそれらず呌ぶものは䜕でも;えヌず、私はこの奇劙な蚀葉が奜きではありたせんから玄束やものを返しおいるので、スピナヌなどを扱うこずができたす。

@gaearonわかりたした、

このスレッドでのサポヌトに満足しおいたす。 私の疑問は今解決されたようです。

関連する新しいディスカッション https 

@gaearon非垞に玠晎らしい説明 トロフィヌありがずう+1

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡