2016-12-31 12 views
0

は私のログイン佐賀の抜粋です:以下サガのライフサイクルに反応

export function* loginFlow() { 
    while (true) { 
    const request = yield take(LOGIN_REQUEST); 
    const { username, password } = request.data; 

    const authResp = yield call(authorize, { username, password }); 
    if (authResp) { 
     yield put({ type: SET_AUTH, newAuthState: true }); // User is logged in (authorized) 
     yield put({ type: CHANGE_FORM, newFormState: { username: '', password: '' } }); // Clear form 
     forwardTo('/home'); // Go to dashboard page 
    } 
    } 
} 

このサガは私LoginContainerです。ログイン画面に戻ってログインコンテナを読み込むたびに、新しい「saga」プロセスが生成されるので、ログイン画面を再訪するたびに、「ログイン」ボタンをクリックするとログインAPIに要求が増えています。ボタン。

コンポーネントが破壊されたときに何とかサーガを破壊することはできますか?

編集:私はAPIリクエストが全く行われているように、初期負荷に二回ログインボタンをクリックする必要があり

export function* loginFlow() { 
    const request = yield take(LOGIN_REQUEST); 
    const { username, password } = request.data; 

    const authResp = yield call(authorize, { username, password }); 
    if (authResp) { 
    yield put({ type: SET_AUTH, newAuthState: true }); // User is logged in (authorized) 
    yield put({ type: CHANGE_FORM, newFormState: { username: '', password: '' } }); // Clear form 
    forwardTo('/home'); // Go to dashboard page 
    } 
} 

export function* watchLogin() { 
    // or takeEvery (according to your business logic) 
    yield* takeEvery(LOGIN_REQUEST, loginFlow); 
} 

export function* root() { 
    const watchers = [ 
    yield fork(watchLogin), 
    ]; 

    // Cancel all watchers on location change 
    yield take(LOCATION_CHANGE); 

    watchers.forEach(function(watcher) { 
    console.log("cancelling watcher") 
    cancel(watcher) 
    }); 
} 

// All sagas to be loaded 
export default [ 
    root, 
]; 

その後、私が経験しています:ここではサガをキャンセルしようとする試みです以前と同じ動作 - サガはキャンセルされず、リクエストは引き続き加算されます。ここで

は私のコンポーネントです:

export class Login extends React.Component { 
    constructor(props) { 
    super(props); 
    this.login = this.login.bind(this); 
    this.onChange = this.onChange.bind(this); 
    } 

    onChange(newFormState) { 
    this.props.dispatch(changeForm(newFormState)); 
    } 

    login(username, password) { 
    console.log("dispatching login request") 
    this.props.dispatch(loginRequest({ username, password })); 
    } 

    render() { 
    const { formState, currentlySending, error } = this.props; 

    return (
     <Wrapper> 
     <LoginForm onChange={this.onChange} data={formState} error={error} currentlySending={currentlySending} btnText={messages.btnText} usernameText={messages.usernameText} passwordText={messages.passwordText} onSubmit={this.login} /> 
     </Wrapper> 
    ); 
    } 
} 

は、ここで私は(routes.js)私のサガをロードする方法は次のとおりです。

export default function createRoutes(store) { 
    // create reusable async injectors using getAsyncInjectors factory 
    const { injectReducer, injectSagas } = getAsyncInjectors(store); 

    return [ 
    { 
     path: '/login', 
     name: 'login', 
     getComponent(nextState, cb) { 
     const importModules = Promise.all([ 
      System.import('containers/Login/reducer'), 
      System.import('containers/Login/sagas'), 
      System.import('containers/Login'), 
     ]); 

     const renderRoute = loadModule(cb); 

     importModules.then(([reducer, sagas, component]) => { 
      injectReducer('login', reducer.default); 
      injectSagas(sagas.default); 
      renderRoute(component); 
     }); 

    importModules.catch(errorLoading); 
    }, 
... 

そして、ここでは、私が問題を引き起こして1であると信じてforwardTo機能です:

function forwardTo(location) { 
    browserHistory.push(location); 
} 

この関数を佐賀のwhileループ内で呼び出す前に壊れてしまった場合、佐賀は破壊されます自動的にすべてが期待どおりに動作します。

答えて

0

まあ、はいあなたはコンポーネント破壊であなたのサガウォッチャーを破壊することができ、そしてそれは二つの方法のいずれかによって、次のようになります。

  1. マウントとアンマウントコンポーネントのアクションに追加し、自分の中でコンポーネントのに反応メソッドcomponentWillMountがマウントアクションをディスパッチし、componentWillUnmountはアンマウントアクションをディスパッチし、それに応じてサガを処理します。

  2. 最初に述べたように( をあなたがページ/コンテナませ部品破壊にあなたのサガウォッチャーを破壊するだろう、と(あなたがそれを使用する場合react-router-reduxから多分)あなただけLOCATION_CHANGEアクションに聞くのではなくCOMPONENT_UNMOUNTアクション
  3. 上記の方法)ここで


はあなたには、いくつかの変更のためにも、自分の佐賀で第二の方法を適用するためのサンプルを行きますあなたのloginFlowサガ・ジェネレータ:

import {call, cancel, fork, put, take} from 'redux-saga/effects'; 
import {takeEvery, takeLatest} from 'redux-saga'; 
import {LOCATION_CHANGE} from 'react-router-redux'; 
import { 
    LOGIN_REQUEST, 
    SET_AUTH, 
    CHANGE_FORM, 
} from './constants'; 

export function* loginFlow() { 
    const request = yield take(LOGIN_REQUEST); 
    const { username, password } = request.data; 

    const authResp = yield call(authorize, { username, password }); 
    if (authResp) { 

    // User is logged in (authorized) 
    yield put({ type: SET_AUTH, newAuthState: true }); 

    // Clear form 
    yield put({ type: CHANGE_FORM, newFormState: { 
     username: '', 
     password: '' 
    } }); 

    forwardTo('/home'); // Go to dashboard page 
    } 
} 

export function* watchLogin() { 
    // or takeEvery (according to your business logic) 
    yield* takeLatest(LOGIN_REQUEST, loginFlow); 
} 

export function* root() { 
    const watchers = [ 
    yield fork(watchLogin), 
    ]; 

    // Cancel all watchers on location change 
    yield take(LOCATION_CHANGE); 
    watchers.forEach(cancel); 
} 

// All sagas to be loaded 
export default [ 
    root, 
]; 

今すぐ上に示され、私たちはその後、LOCATION_CHANGE上ウォッチャーを破壊するをキャンセルを使用するコンポーネント/コンテナの使用にredux-saga/effectsにフォークサガウォッチャーの一部を使用。

さらに、LoginComponentのbuttonClickにLOGIN_REQUESTアクションをディスパッチする必要があります。


明確でないものがあるかどうかを尋ねてください。

redux-saga文書hereからのタスクキャンセルの詳細については、こちらをご覧ください。

+0

上記のコードを実装しようとしていた元の投稿を編集しました。私はまだ奇妙な動作をしていますし、サガはキャンセルされません。 – Nirri

+0

私はサガをどこに注入/ロードするのですか?また、不適切な機能を調査するためにReactコンポーネントを書き留めますか? –

+0

元の投稿をいくつかの追加データで編集しました – Nirri

関連する問題