我想在使用withRouter in web的webservice获得响应之后重定向到特定页面

时间:2017-11-22 06:21:54

标签: reactjs typescript react-redux

我需要帮助,了解如何在使用typescript中的react和reactx中的axios从web服务获得响应后,如何重定向到页面。 就我而言,甚至在生成响应之前,页面就会直接重定向到新页面。 以下是相同的代码段。

## Component.jsx ##

import * as React from 'react';
import { Constants } from '../../../constants';
import { withRouter } from 'react-router-dom';
import '../styles/LoginPage.css';
import { store } from '../../../store';
import addSessionID from './../actions/LoginAction';
const logo = require('../../../assets/images/logo.png');
const footer = require('../../../assets/images/veras-logo.png');

class Login extends React.Component<any, {}> {
  public refs: { username: HTMLInputElement,
                password: HTMLInputElement };
  constructor(props: any) {
    super(props);

    this.onSubmit = this.onSubmit.bind(this);
  }
  onSubmit(event: any): void {
    event.preventDefault();
    const headers: any = {
            'Authorization': 'Basic ' + window.btoa(this.refs.username.value + ':' + this.refs.password.value),
            'content-type': 'application/json'
          };
    const URL = 
    Constants.VERAS_API.SESSION.BASE_URL + 
    Constants.VERAS_API.SESSION.LOGIN + 
    Constants.VERAS_API.SESSION.APPLICATION_ID_STRING ;
    store.dispatch(addSessionID(URL, headers));
    // this.props.history.push('/Dashboard');
  }

  render() {
    const username = 'username';
    const password = 'password';
    return (
      <div className="full-container">
        <div className="login-container">
          <div className="login-body">
            <div className="login-header">
              <img src={logo} alt="" />
            </div>
            <h3>{Constants.LANGUAGES.EN_US.LOGIN.LABELS.LOGIN_FORM}</h3>
            <form
              name="form"
              method="post"
              className="login-form"
              onSubmit={this.onSubmit}
            >
              <div className="col-md-10">
                <ul>
                  <li>
                    <label>
                      {Constants.LANGUAGES.EN_US.LOGIN.LABELS.USERNAME_FIELD}
                    </label>
                    <input
                      type="text"
                      className="form-control"
                      name={username}
                      ref={username}
                      required={true}
                    />
                  </li>
                  <li>
                    <label>
                      {Constants.LANGUAGES.EN_US.LOGIN.LABELS.PASSWORD_FIELD}
                    </label>
                    <input
                      type="password"
                      className="form-control"
                      name={password}
                      ref={password}
                      required={true}
                    />
                  </li>
                </ul>

                <span className="forgotpass">
                  {Constants.LANGUAGES.EN_US.LOGIN.LABELS.FORGOT_PASSWORD_LINK}
                </span>
                <button className="login-btn" >
                  {Constants.LANGUAGES.EN_US.LOGIN.LABELS.LOGIN_BUTTON}
                </button>
              </div>
            </form>
            <span className="login-footer-logo">
              <img src={footer} alt="" />
            </span>
          </div>
        </div>
      </div>
    );
  }
}

export default withRouter(Login);

Action.tsx

import axios from 'axios';
import { Constants } from '../../../constants';

export default function addSessionID(apiUrl: string, headers: any): any {
  const URL =
    Constants.VERAS_API.SERVER.SCHEME +
    '//' +
    Constants.VERAS_API.SERVER.HOSTNAME +
    Constants.VERAS_API.SERVER.PORT;
  const finalURL = URL + apiUrl;
  console.log(URL);
  return function(dispatch: any) {
    axios
      .post(
        finalURL,
        {},
        {
          headers: headers
        }
      )
      .then(response => {
        if (response.data.sessionId) {
          // history.pushState('', '', '/Dashboard');
          dispatch({
            type: 'LOGIN_SUCCESSFUL',
            payload: response.data.sessionId
          });
        }
      })
      .catch(error => {
        dispatch({
            type: 'LOGIN_FAILED',
            payload: error
          });
      });
  };
}

Reducer.tsx

interface InitialState {
  session_id: string;
  login_status: boolean;
  error: string;
}

export const loginReducer = (
  state: InitialState = { session_id: '', login_status: false, error: '' },
  action: any
): any => {
  console.log('Reducer', action.payload);
  switch (action.type) {
    case 'LOGIN_SUCCESSFUL':
      state = { session_id: action.payload, login_status: true, error: ''};
      console.log(state);
      return state;
    case 'LOGIN_FAILED':
        state = {session_id: 'null', login_status: false, error: action.payload };
        console.log(state);
        return state;
    default:
      return state;
  }
};

store.tsx

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import combineReducers from './combinedReducer';

export const store = createStore(combineReducers, applyMiddleware(thunk));

combineReducer.tsx

import { combineReducers } from 'redux';
import { loginReducer } from './modules/user/reducers/LoginReducer';

export default combineReducers({
  loginReducer
});

App.tsx

import * as React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Login from './modules/user/components/Login';
import Dashboard from './modules/dashboard/components/Dashboard';
import './assets/css/App.css';

// const logo = require('./logo.svg');

class App extends React.Component<{}, {}> {
  render() {
    return (
      <Router>
        <Switch>
          <Route exact={true} path="/" component={Login} />
          <Route exact={true} path="/Dashboard" component={Dashboard} />
        </Switch>
      </Router>
    );
  }
}

export default App;

index.tsx

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import App from './App';
import { Provider } from 'react-redux';
import registerServiceWorker from './registerServiceWorker';
import './assets/css/index.css';
import { store } from './store';

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root') as HTMLElement
);
registerServiceWorker();

的package.json

{
  "name": "veras-reach-typescript",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@types/react-router-dom": "^4.2.1",
    "axios": "^0.17.1",
    "react": "^16.1.1",
    "react-dom": "^16.1.1",
    "react-redux": "^5.0.6",
    "react-router-dom": "^4.2.2",
    "react-scripts-ts": "2.8.0",
    "redux": "^3.7.2",
    "redux-logger": "^3.0.6",
    "redux-thunk": "^2.2.0"
  },
  "scripts": {
    "start": "react-scripts-ts start",
    "build": "react-scripts-ts build",
    "test": "react-scripts-ts test --env=jsdom",
    "eject": "react-scripts-ts eject"
  },
  "devDependencies": {
    "@types/jest": "^21.1.6",
    "@types/node": "^8.0.53",
    "@types/react": "^16.0.25",
    "@types/react-dom": "^16.0.3",
    "@types/react-router": "^4.0.17",
     "eslint": "^4.11.0"
  }
}

有人可以帮我解决重定向问题吗?

1 个答案:

答案 0 :(得分:2)

您可以检测道具中的更改,然后可以重定向到组件本身的页面,如

componentWillReceiveProps(newProps){
    if(newProps.login_status){ // Redirect if login status become true
       this.props.history.push('/Dashboard')
    }
}

或者您可以签入render方法,例如

render() {
    if (this.props.login_status) { // Redirect if login status true
         this.props.history.push('/Dashboard');
    }
    return <LoginComponent /> // Component name changed for understanding
}