无法在React Router v4中推送历史记录(无编程路由)

时间:2017-07-10 16:42:47

标签: reactjs routing react-router browser-history react-router-v4

我很难获得反应路由器v4来推送基于if语句条件的程序化历史记录。点按钮上的所有路由都可以正常工作,但我无法让历史记录正常工作。我得到的错误是:

TypeError: Cannot read property 'push' of undefined

这是

self.props.history.push('/picturemain')

很明显,在我的组件中,它并不认为历史是定义的。我不确定我做错了什么。这是我的路由页面:

import React from 'react'
import { Switch, Route,  BrowserRouter as Router } from 'react-router-dom'
import { injectGlobal, ThemeProvider } from 'styled-components'

import { HomePage, AboutPage, PictureSwapper, PostsPage, Posts1, Posts2, Posts3, Posts4, PostsArchive, MessagePage, PictureMain } from 'components'

const App = () => {
  return (
    <ThemeProvider theme={theme}>
      <Router>
        <div>
        <Route path="/" component={Posts3} exact />
        <Route path="/home" component={HomePage} exact />
        <Route path="/about" component={AboutPage} exact />
        <Route path="/posts" component={PostsPage} exact />
        <Route path="/pictureswapper" component={PictureSwapper} exact />
        <Route path="/message" component={MessagePage} exact />
        <Route path="/postpages/1" component={Posts1} exact />
        <Route path="/postpages/2" component={Posts2} exact />
        <Route path="/postpages/3" component={Posts3} exact />
        <Route path="/postpages/4" component={Posts4} exact />
        <Route path="/postsarchive" component={PostsArchive} exact />
        <Route path="/picturemain" component={PictureMain} exact />
        </div>
      </Router>
    </ThemeProvider>
  )
}

export default App

这是我的页面,其中包含了推向历史的条件。条件成功到达后端,并且仅抛出错误,因为历史未定义。

import React, { Component, PropTypes } from 'react'
import { Badge, IconButton, Heading, Paragraph, ParagraphHolder, 
PrimaryNavigation, 
SecondaryNavigation, TertiaryNavigation, 
Caption, Link, ParagraphSmall, AlignContainer,
SubHeader, PictureMain} from 'components'
import renderIf from 'render-if'
import styled from 'styled-components'
import axios from 'axios'
import {
  BrowserRouter as Router,
  Route,
  Redirect,
  Switch
} from 'react-router-dom';


class PictureLogin extends Component{

  static propTypes = {
    history: PropTypes.object.isRequired
  }

  constructor(props){
    super(props);
    this.state = {
      name: '',
      password: '',
      redirect: ''
    }
  }

  registerClick(e){
    e.preventDefault();
    var self = this;
    axios.post('http://localhost:5000/register', {
      name: this.state.name,
      password: this.state.password
    })
      .then((response)=>{
       console.log('response from the python call ', response.data);
       if(response.data === 'usersuccessfullyadded'){
        self.props.history.push('/picturemain')
       }
      })
     .catch(()=>{
       console.log('python axios error');
     });
  }

  loginClick(e){
    e.preventDefault();
    var self = this;
    axios.post('http://localhost:5000/login', {
      name: this.state.name,
      password: this.state.password
    })
      .then((response)=>{
       console.log('response from the python call ', response.data);
       if(response.data === 'passwordsmatch'){
        console.log(self.props)
        self.props.history.push('/picturemain')
       }
     })
     .catch((err)=>{
       console.log('python axios error');
       console.log('and the error is ', err);
     });
  }

  resetRedirect(){
    this.setState({
      redirect: ""
    })
  }

  render(){
    return(
        <FlexContainer>
          <FlexRow>
            <div>Login</div>

            <input  value={this.state.name}
               onChange={(e)=>{this.setState({name: e.target.value})}} 
               type="username" name="username" placeholder="User Name"/><br/>

            <input  value={this.state.password} 
               onChange={(e)=>{this.setState({password: e.target.value})}} 
               type="password" name="password" placeholder="Password"/><br/>

            <button onClick={(e)=>this.registerClick(e)}>Register</button>
            <button onClick={(e)=>this.loginClick(e)}>Login</button>
          </FlexRow>
        </FlexContainer>
    )
  }
}



export default PictureLogin

FlexContainer和FlexRow是我自己的样式组件,未在此处声明。这样的样式就好了,我只是把它拿出来以便于阅读。

编辑:有人在这里与可能的欺骗有关:How to navigate dynamically using react router dom。该修复应该是我将其添加到标题import {withRouter} from 'react-router-dom';并导出为此export default withRouter(PictureLogin);。我已做出这些更改并且有更改 - 现在我正在路由,但是到了空白页面!所以...我会打开这个问题因为有明显的错误。我路由到的页面具有可渲染数据,但由于某种原因不能渲染。这不是一个有效的修复方法。

我正在渲染的组件是一个简单的hello世界,以确保我没有包含任何会破坏它的奇怪东西。这是我尝试路由到的组件:

import React, { Component } from 'react'
import renderIf from 'render-if'
import styled from 'styled-components'
import axios from 'axios'


class PictureMain extends Component{
  constructor(props){
    super(props);
    this.state = {
    }
  }

  render(){
    return(
      <div>
        hello world
      </div>
    )
  }
}



export default PictureMain

2 个答案:

答案 0 :(得分:1)

据我所知,您的代码PictureLogin未使用<Route path="/" component={PictureLogin} exact />

如果是这种情况,我认为<Route />组件将history, match and location传递给用作<Route path="/" component={someComponent} />的组件

对于其他组件,如果要访问history,可以使用名为withRouter的HOC包装组件

您可以将其导入为: import { withRouter } from 'react-router-dom'

之后,如果您将导出默认值更新为

export default withRouter(PictureLogin)不应该是Cannot read property 'push' of undefined

答案 1 :(得分:0)

我必须在我的路线中为我的PictureMain页面执行以下操作。我不确定为什么,但它现在有效。我以这种方式包括它:

import PictureMain from './pages/picturepages/PictureMain'

这是令人沮丧的,因为其他人可以被包括在括号中,但不是这个。嗯...无论如何,我现在已经解决了,因为我已经得到了解决方案。感谢大家的帮助。