2017-12-18 16 views
0

バックグラウンド:
私はLoginコンポーネントを作成しています。redux sagaとhistory.push

saga.jsは、3つの関数
で構成されています。 の中のsagasのリストを実行します。送信ボタンをクリックしてアクションをディスパッチします。
バックエンドはReact400を返す:戻り値はpromiseオブジェクトアクションで

あるaxios.post受け取る
action及びプロセスを派遣しました。この場合は問題ありません。​​とrender()に簡単に表示できます。しかし、200が返されたとき。 私は、ユーザにURL /companiesに行かせる必要があります。

試み:
私がしようとしたがcomponentWillUpdate()this.props.history.push('/companies');を置くが、それは動作しません。私はSubmitを2回クリックしてReactを取得しなければならないと理解していますtokenが保存されました。

Login.js

import React, {Component} from 'react'; 
import ErrorMessage from "../ErrorMessage"; 
import {Field, reduxForm} from 'redux-form'; 
import {connect} from 'react-redux'; 
import {validate} from '../validate'; 
import {SUBMIT_USERNAME_PASSWORD} from "../../constants"; 

class Login extends Component { 

    constructor(props) { 
    //Login is stateful component, but finally action will change 
    //reducer state 
    super(props); 
    const token = localStorage.getItem('token'); 
    const isAuthenticated = !((token === undefined) | (token === null)); 
    this.state = { 
     token, 
     isAuthenticated, 
     message: null, 
     statusCode: null 
    }; 
    } 

    onSubmit(values) { 
    const {userid, password} = values; 
    const data = { 
     username: userid, 
     password 
    }; 
    this.props.onSubmitClick(data); 
    } 

    componentWillUpdate(){ 
    console.log('componentWillUpdate'); 
    if(this.props.isAuthenticated){ 
     this.props.history.push('/companies'); 
    } 
    } 

    renderField(field) { 
    const {meta: {touched, error}} = field; 
    const className = `'form-group' ${touched && error ? 'has-danger' : ''}`; 

    console.log('renderField'); 

    return (
     <div className={className}> 
     <label>{field.label}</label> 
     <input 
      className="form-control" 
      type={field.type} 
      placeholder={field.placeholder} 
      {...field.input} 
     /> 
     <div className="text-help"> 
      {touched ? error : ''} 
     </div> 
     </div> 
    ); 
    } 

    render() { 
    const {handleSubmit} = this.props; 

    return (
     <div> 
     <ErrorMessage 
      isAuthenticated={this.props.isAuthenticated} 
      message={this.props.message} 
     /> 

     <form onSubmit={handleSubmit(this.onSubmit.bind(this))}> 
      <Field 
      name="userid" 
      component={this.renderField} 
      placeholder="User ID" 
      type="text" 
      /> 
      <Field 
      name="password" 
      component={this.renderField} 
      placeholder="Password" 
      type="password" 
      /> 
      <button type="submit" className="btn btn-primary">Submit</button> 
     </form> 
     <a className='btn btn-primary' href="https://www.magicboxasia.com/">Sign up</a> 
     </div> 
    ); 
    } 
} 


const onSubmitClick = ({username, password}) => { 
    return { 
    type: SUBMIT_USERNAME_PASSWORD, 
    payload: {username, password} 
    }; 
}; 

const mapStateToProps = (state, ownProps) => { 
    return { 
    ...state.login 
    } 
}; 

export default reduxForm({ 
    validate, 
    form: 'LoginForm' 
})(
    connect(mapStateToProps, {onSubmitClick})(Login) 
); 

saga.ja

const shootApiTokenAuth = (values) =>{ 
    const {username, password} = values; 
    return axios.post(`${ROOT_URL}/api-token-auth/`, 
    {username, password}); 
}; 

function* shootAPI(action){ 
    try{ 
    const res = yield call(shootApiTokenAuth, action.payload); 
    yield put({ 
     type: REQUEST_SUCCESS, 
     payload: res 
    }); 
    }catch(err){ 
    yield put({ 
     type: REQUEST_FAILED, 
     payload: err 
    }); 
    } 
} 

function * watchSubmitBtn(){ 
    yield takeEvery(SUBMIT_USERNAME_PASSWORD, shootAPI); 
} 

// single entry point to start all Sagas at once 
export default function* rootSaga() { 
    yield all([ 
    watchSubmitBtn() 
    ]) 
} 

問題:
私はURL /companiesにコンポーネントの状態とpushを設定できますか?バックエンド後に200を返しますか?

+0

私はhttps://stackoverflow.com/questions/42893161/how-to-provide-a-history-instance-to-a-sagaを読まなく、理解していなかった – Sarit

答えて

1

私は通常、佐賀のような条件付きナビゲーションを処理します。

既存のコードとの最も簡単な答えはSUBMIT_USERNAME_PASSWORDアクションで小道具として履歴オブジェクトを渡し、佐賀の成功事例にhistory.push()の呼び出しを行うことです、何かのように:

const onSubmitClick = ({username, password}) => { 
    const { history } = this.props; 

    return { 
    type: SUBMIT_USERNAME_PASSWORD, 
    payload: {username, password, history} 
    }; 
}; 

.......

function* shootAPI(action){ 
    try{ 
    const res = yield call(shootApiTokenAuth, action.payload); 
    const { history } = action.payload; 

    yield put({ 
     type: REQUEST_SUCCESS, 
     payload: res 
    }); 

    history.push('/companies'); 
    }catch(err){ 
    yield put({ 
     type: REQUEST_FAILED, 
     payload: err 
    }); 
    } 
} 
+0

私は歴史を伝えることができます!どうもありがとうございました。私はいつも 'this'で接頭辞付けられたすべてのプロパティは他のファイルに渡すことができません。しかし、私は間違っていました。 – Sarit

0

リアクションには追加のライフサイクルがあります。私は今日それを知っています。彼らはそれらの多くです。

componentDidUpdate() { 
    this.props.history.push('/companies'); 
    } 
関連する問題