【问题标题】:I want to redirect to a particular page after getting response from webservice using withRouter in react我想在使用 withRouter 从 web 服务获得响应后重定向到特定页面
【发布时间】:2017-11-22 06:21:53
【问题描述】:

我需要帮助来了解如何在我使用 axios in react 和 redux 使用 typescript 从 Web 服务获得响应后重定向到页面。 就我而言,即使在生成响应之前,页面也会直接重定向到新页面。 下面是相同的代码sn-p。

## 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"
  }
}

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

【问题讨论】:

标签: reactjs typescript react-redux


【解决方案1】:

您可以检测道具的变化,然后可以重定向到组件本身的页面,例如

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
}

【讨论】:

  • 谢谢,我还有一个疑问。在我的 reducer 中设置的初始状态有 'session_id' 有 ' ',当我点击登录按钮时,它给了我存储在 redux 中的 session_id,即空白,因为我没有收到来自 Web 服务的任何响应。如果我再次单击该按钮,它会为我提供上一个 session_id 并存储来自 Web 服务的新 session_id。那么我该如何解决这个问题呢?
  • @Advait - 你仍然得到以前的会话 id 而不是当前的会话 id?你从商店得到什么?对不起,如果我理解错误..
  • 我将日志粘贴到 cmets:-inside dispatch Login.tsx:38 ==== {session_id: "", login_status: false, error: ""} LoginReducer.tsx:11 Reducer bee03a9822824f8eb12a4773e287e4bb LoginReducer.tsx:15 {SESSION_ID: “bee03a9822824f8eb12a4773e287e4bb”,login_status:真,错误: “”} Login.tsx:38 ==== {SESSION_ID: “bee03a9822824f8eb12a4773e287e4bb”,login_status:真,错误: “”} LoginReducer.tsx :11 减速器 f0496644d3344d3fbfd8e73854de91bc LoginReducer.tsx:15 {session_id: "f0496644d3344d3fbfd8e73854de91bc", login_status: true, error: ""}
  • 我也不能使用“dispatch(push('/Dashboard'))”。而不是重定向它给了我调度的日志
  • @Advait - 像return { ...state, session_id: action.payload, login_status: true, error: ''} 一样在你的reducer 中包装初始状态并尝试dispatch(push("/Dashboard")) 只有在你使用react-router-redux 时才有效。因此,请尝试上面提供的替代选项。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-26
  • 1970-01-01
  • 2021-11-22
相关资源
最近更新 更多