Backgrond:Login
コンポーネントを作成しています。
_saga.js
_は3つの関数で構成されています
1。 rootSaga
。内部でsagas
のリストを実行します
2。 watchSubmitBtn
。送信ボタンのクリックを監視し、アクションをディスパッチします。
3。 shootApiTokenAuth
はディスパッチされたaction
を受け取り、_axios.post
_を処理します。戻り値はpromise
オブジェクトです
動作中:
バックエンドは_400
_をReact
に返します。この場合、payload
を読み取ってrender()
に簡単に表示できます。ただし、_200
_が返された場合。ユーザーに_/companies
_というURLにアクセスさせる必要があります。
試行: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
_を返した後?
私は通常、佐賀でそのような条件付きナビゲーションを処理します。
既存のコードで最も簡単な答えは、履歴オブジェクトを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
});
}
}
import { Push } from 'react-router-redux';
yield put(Push('/path-to-go'));
私の問題を解決しました
私は反応の経験はあまりありませんが、次のようにして達成できます。
1.新しいモジュールを作成します:history-wrapper.ts
export class HistoryWrapper {
static history;
static init(history){
HistoryWrapper.history = history;
}
}
2.あなたの中login.jsx
HistoryWrapper.init(history);//initialize history in HistoryWrapper
3.アプリ内のその後の任意の場所
HistoryWrapper.history.Push('/whatever');
Reactには追加のライフサイクルがあります。今日はそれを知っています。それらの多くです。
componentDidUpdate() {
this.props.history.Push('/companies');
}