REDO传奇和history.push

背景:
我正在创建一个Login组件。REDO传奇和history.push

saga.js由3个函数组成
1. rootSaga。它将执行sagas的列表
内部的watchSubmitBtn。它会观察提交按钮上的点击并发出一个动作。
3. shootApiTokenAuth将收到出动action和处理axios.post返回值是promise对象

在行动:
后端返回400React。这种情况下没有问题,我可以轻松读取​​并在render()中显示。但是,当返回200。 我需要让用户转到网址/companies

尝试:
我曾试图把this.props.history.push('/companies');componentWillUpdate(),但它不工作。我必须点击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()

])

}

问题:
我如何设置组件的状态,并push到URL /companies?后端返回200

回答:

我通常会处理像saga这样的条件导航。

与现有的代码最简单的答案是通过一个历史记录对象作为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

});

}

}

回答:

React有额外的生命周期。我今天才知道。他们中的很多人。

componentDidUpdate() { 

this.props.history.push('/companies');

}

以上是 REDO传奇和history.push 的全部内容, 来源链接: utcz.com/qa/261819.html

回到顶部