【问题标题】:URL changing but view is not changing in React Router 4URL 改变但视图在 React Router 4 中没有改变
【发布时间】:2017-11-14 12:58:57
【问题描述】:

我使用的是反应路由器 4 而不是反应路由器 3,所以我使用的是 react-router-dom。我试图让 this.props.history.push 工作,但它所做的只是保持视图不变,但 URL 会发生变化。

例如,我单击按钮,它会调用一个函数,该函数只调用 this.props.history.push('/posts')。 url 从 localhost:3000/signin 更改为 localhost:3000/posts。但我仍然在我的登录视图中。

如果我点击刷新,它会重定向到帖子页面。我查看了其他问题,这些人无论如何都无法让它去那里,即使他们刷新或进入网址并按回车键。

我将在下面发布代码,看看我做错了什么。另外我使用的是 react router v4 而不是 3。我不能使用 browserHistory.push 和 v3 使用的其他东西。

代码:

组件:

import React, { Component } from 'react';
import {Field, reduxForm} from 'redux-form';
import {connect} from 'react-redux';
import * as actions from '../../actions';
import {withRouter} from 'react-router';

class Signin extends Component {
  constructor(props) {
    super(props);

    this.onSubmit = this.onSubmit.bind(this);
  }

  renderField(field) {
    const { meta: {touched, error} } = field;
    const className = `form-group ${touched && error ? 'has-danger' : ''}`;

    return (
      <div className={className}>
        <label><strong>{field.label}:</strong></label>
        <input
          className="form-control"
          type={field.type}
          {...field.input}
        />
        <div className="text-help">
          { touched ? error : ''}
        </div>
      </div>
    )
  }

  onSubmit({email, password}) {
    // this.props.signinUser({email, password}, () => {
      this.props.history.push('/posts');
    // });
  }

  renderAlert() {
    if(this.props.errorMessage) {
      return (
        <div className="alert alert-danger">
          <strong>Oops</strong> {this.props.errorMessage}
        </div>
      )
    }
  }

  render() {
    const { handleSubmit } = this.props;

    return (
      <form onSubmit={handleSubmit(this.onSubmit)}>
        <Field
          label="Email"
          name="email"
          type="email"
          component={this.renderField}
        />
        <Field
          label="Password"
          name="password"
          type="password"
          component={this.renderField}
        />
        {this.renderAlert()}
        <button type="submit" className="btn btn-success">Sign In</button>
      </form>
    );
  }
}

function validate(values) {
  const errors = {};

  //Validate the inputs from values
  if(!values.email) {
    errors.email = "Enter an email!";
  }
  if(!values.password) {
    errors.password = "Enter a password!";
  }
  //If errors is empty, the form is fine to submit
  //If errors has any properties, redux form assumes form is invalid
  return errors;
}

function mapStateToProps(state) {
  return {
    errorMessage: state.auth.error
  };
}

export default reduxForm({
  validate,
  form: 'signin'
})(connect(mapStateToProps, actions)(withRouter(Signin)));

动作:

export function signinUser({email, password}, cb) {
  return function(dispatch) {
    axios.post(`${ROOT_URL}/signin`, {email, password})
      .then((response) => {
        dispatch({type: AUTH_USER});
        localStorage.setItem('token', response.data.token);

      })
      .then(() => cb())
      .catch((error) => {
        dispatch(authError(error.response.data.error));
      })
  }
}

【问题讨论】:

    标签: reactjs redux react-router


    【解决方案1】:

    我发现问题不在于我发布的代码,而在于我如何处理路线。确保在路由时不会将路由作为组件嵌套为路由。例如我有:

    const Routes = (
      <Provider store={store}>
        <BrowserRouter>
        <App />
        </BrowserRouter>
      </Provider>
    )
    

    这里我已经将 App 作为组件导入(或作为组件导出),我将其从组件更改为普通函数。为了更清楚地说明这一点,我将把旧代码和新代码放在下面:

    旧:

    class App extends React.Component {
     render() {
      return (
       <div>
        <Switch>
          <Route exact path='/' component={Home} />
          <Route path="/signin" component={RequireUnAuth(Signin)} />
          <Route path="/signout" component={Signout} />
          <Route path="/signup" component={Signup} />
          <Route path="/posts" component={Posts} />
        </Switch>
       </div>
      )
     }
    }
    

    新:

    const App = () => (
       <div>
        <Switch>
          <Route exact path='/' component={Home} />
          <Route path="/signin" component={RequireUnAuth(Signin)} />
          <Route path="/signout" component={Signout} />
          <Route path="/signup" component={Signup} />
          <Route path="/posts" component={Posts} />
        </Switch>
       </div>
      )
    

    这是正在导出的应用程序,一旦我切换到一个简单的函数而不是基于组件的类,一切正常。我不必进行硬刷新,我可以单击返回并返回,使用 this.props.history.push 进行重定向等工作......

    【讨论】:

      【解决方案2】:

      确保您安装了最新版本的 react-router-redux (https://github.com/reactjs/react-router-redux),支持 React Router 4。在 package.json 中:

      "react-router-redux": "next"

      接下来,按照说明将历史中间件添加到您的 redux 存储。链接:https://github.com/reactjs/react-router-redux#what-if-i-want-to-issue-navigation-events-via-redux-actions

      一旦你安装了正确的包和中间件,你需要将reducer导入你的index reducer,例如:

      import {combineReducers} from 'redux';
      import {routerReducer} from 'react-router-redux';
      
      const IndexReducer = combineReducers({
          router: routerReducer,
          //...other reducers go here
      });
      
      export default IndexReducer;
      

      然后,将 push 方法导入您想要分派的任何位置(例如 actions.js):

      import {push} from 'react-router-redux';

      然后像这样使用它:

      dispatch(push('/your/route/here'));

      【讨论】:

      • 我使用的是 react-router-dom 而不是 react-router-redux
      • 对不起,我没有 react-router-redux
      • 这不是react-router-redux,而是react-router-dom,请问两者是否相同?我无法让它工作。
      猜你喜欢
      • 1970-01-01
      • 2019-07-01
      • 2022-06-14
      • 2020-02-08
      • 1970-01-01
      • 2015-05-05
      • 2020-02-12
      • 2021-10-21
      • 1970-01-01
      相关资源
      最近更新 更多