URL 更改但视图在 React Router 4 中未更改 [英] URL changing but view is not changing in React Router 4

查看:39
本文介绍了URL 更改但视图在 React Router 4 中未更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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

代码:

组件:

import React, { Component } from 'react';从 'redux-form' 导入 {Field, reduxForm};从'react-redux'导入{connect};从'../../actions'导入*作为动作;从反应路由器"导入{withRouter};类登录扩展组件{构造函数(道具){超级(道具);this.onSubmit = this.onSubmit.bind(this);}渲染场(场){const { meta: {touched, error} } = field;const className = `form-group ${touched &&错误 ?'有危险':''}`;返回 (

<label><strong>{field.label}:</strong></label><输入className="表单控件"type={field.type}{...field.input}/><div className="text-help">{摸了?错误 : ''}

)}onSubmit({email, password}) {//this.props.signinUser({email, password}, () => {this.props.history.push('/posts');//});}渲染警报(){如果(this.props.errorMessage){返回 (<div className="alert alert-danger"><strong>糟糕</strong>{this.props.errorMessage}

)}}使成为() {const { handleSubmit } = this.props;返回 (<form onSubmit={handleSubmit(this.onSubmit)}><字段标签=电子邮件"名称=电子邮件"类型=电子邮件"组件={this.renderField}/><字段标签=密码"名称=密码"类型=密码"组件={this.renderField}/>{this.renderAlert()}<button type="submit" className="btn btn-success">登录</button></表单>);}}功能验证(值){常量错误 = {};//验证来自值的输入如果(!values.email){errors.email = "输入邮箱!";}如果(!值.密码){errors.password = "请输入密码!";}//如果errors为空,表单就可以提交//如果错误有任何属性,redux 表单假定表单无效返回错误;}函数 mapStateToProps(state) {返回 {错误消息:state.auth.error};}导出默认 reduxForm({证实,形式:'签到'})(connect(mapStateToProps, actions)(withRouter(Signin)));

动作:

export function signinUser({email, password}, cb) {返回函数(调度){axios.post(`${ROOT_URL}/signin`, {email, password}).then((响应) => {调度({类型:AUTH_USER});localStorage.setItem('token', response.data.token);}).then(() => cb()).catch((错误) => {dispatch(authError(error.response.data.error));})}}

解决方案

我发现问题不在我发布的代码中,而是我如何处理我的路由.确保在路由时您没有将路由作为组件嵌套为路由.例如我有:

const 路由 = (<提供者商店={商店}><浏览器路由器><应用程序/></BrowserRouter></提供者>)

这里我把App作为组件导入(或者是作为组件导出),我把它从一个组件改成了一个普通的函数.为了更清楚地说明这一点,我将把旧代码和新代码放在下面:

旧:

class App 扩展 React.Component {使成为() {返回 (<div><开关><路由精确路径='/' component={Home}/><Route path="/signin" component={RequireUnAuth(Signin)}/><Route path="/signout" component={Signout}/><Route path="/signup" component={Signup}/><Route path="/posts" component={Posts}/></开关>

)}}

新:

const App = () =>(<div><开关><路由精确路径='/' component={Home}/><Route path="/signin" component={RequireUnAuth(Signin)}/><Route path="/signout" component={Signout}/><Route path="/signup" component={Signup}/><Route path="/posts" component={Posts}/></开关>

)

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

I am using react router 4 not react router 3 so I am using react-router-dom. I am trying to get this.props.history.push to work, but all it is doing is keeping the view the same, but the URL changes.

For example I click the button and it calls a function which just calls this.props.history.push('/posts'). The url changes from localhost:3000/signin to localhost:3000/posts. But I am still on my signin view.

If I hit refresh however it will redirect to the posts page. I have looked at other questions and those people could not get it to go there no matter what, even if they refreshed or went into the url and hit enter.

I will post the code below to see what I am doing wrong. Also I am using react router v4 not 3. I cannot use browserHistory.push and other things that v3 used.

Code:

component:

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)));

action:

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));
      })
  }
}

解决方案

I found out the problem was not within the code I posted but how I was doing my routes. Make sure when you are routing you are not nesting routes as components as your routes. For example I had:

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

Here I had imported App as a component (or it was exported as a component), I changed it from a component to a normal function. To make this more clear I will put old code and new code below:

Old:

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>
  )
 }
}

New:

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 is the App that was being exported and once I switched to a simple function instead of a component based class everything worked. I didn't have to do hard refreshes, I can click back and it goes back, redirecting with this.props.history.push works, etc...

这篇关于URL 更改但视图在 React Router 4 中未更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆