2017-12-18 20 views
0

backgrond에를 history.push :
나는 Login 구성 요소를 만드는 오전.REDUX 사가과

saga.js은 3 개의 함수
으로 구성됩니다. 안에 sagas의 목록을 실행합니다. 제출 버튼을 클릭하여 조치를 전달합니다.
백엔드가 React400를 반환 반환 값이 promise 객체 행동

입니다 axios.post 받게됩니다
3. shootApiTokenAuthaction 및 프로세스를 파견. 이 경우에는 아무런 문제가 없으며 payload을 읽고 render()에 쉽게 표시 할 수 있습니다. 그러나 200이 반환 될 때. 사용자가 /companies이라는 URL로 이동하게해야합니다.

는 시도 : 나는 시도했다
componentWillUpdate()this.props.history.push('/companies');을 넣어,하지만 작동하지 않습니다. 를 클릭해야합니다 Submit 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() 
    ]) 
} 

문제 : 구성 요소 상태 push을 설정할 수 있습니다
어떻게 /companies를 URL에? 백엔드 후 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'); 
    }