簡體   English   中英

為什么選擇React-router v4 <Link/> 不起作用(更改網址但不提取內容)?

[英]Why React-router v4 <Link/> does not work (Changes url but not rendering content)?

我有服務器端React / Redux / Express應用程序。 React-router v4為使用Switch的服務器應用程序提供解決方案,我需要使用一些東西來改變我的NavBar組件的位置

應用

import React, { Component } from 'react'

import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'

import { Switch, Route, Redirect, Link} from 'react-router-dom'
import FirstPage from './FirstPage'
import Test from './Test'
import LoginPage from './login/LoginPage'
import NoMatch from '../components/NoMatch'
import NavBar from '../components/NavBar'

import * as loginActions from '../actions/login'

import 'bootstrap/dist/css/bootstrap.css';

class App extends Component {

  render(){
    return (
      <div>
            <NavBar/>

            <h1>EffortTracker v3.0.1</h1>

        <Switch >
            <Route exact path="/" render={loginRedirect(<FirstPage/>)}/>
              <Route path="/first" render={loginRedirect(<FirstPage/>)}/>
              <Route path="/second" render={loginRedirect(<Test/>)}/> />
              <Route path="/login" render={()=><LoginPage {...this.props.login}/>} />
              <Route component={NoMatch}/>
        </Switch>

          <Link to={'/first'}>First</Link>
      </div>
    )
  }
}

const loginRedirect=(component) => {
    if(!isLoggedIn()) return ()=> <Redirect to='login'/>

    return ()=> component
}

const isLoggedIn= ()=>{
    let token = localStorage.getItem('token')

if (token !== null)return false
    else return true

}

const mapStateToProps = state => ({
    login: state.login,
    error: state.error,
    isLoading: state.isLoading,
})

const mapDispatchToProps = dispatch => ({
    loginActions: bindActionCreators(loginActions, dispatch)
})

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(App)

需要從NavBar更改

import React from 'react'
import { Link, NavLink } from 'react-router-dom'

import classnames from 'classnames'

const NavBar =()=> {
    return (
        <nav className={classnames("navbar", "navbar-inverse bg-inverse")}>
            <form className="form-inline">
                <Link to={'/'}>
                    <button className={classnames("btn", "btn-sm", "align-middle", "btn-outline-secondary")}
                            type="button">
                        Smaller button
                    </button>
                </Link>

                <NavLink to='/login'>
                    Login
                </NavLink>
            </form>

        </nav>
    )
  }

export default NavBar

如果我從瀏覽器URL手動導航它的工作就好了,但如果我點擊鏈接或NavLink網址更新但不是應用程序切換。 當loginRedirect到/ login它沒有出現並且需要刷新頁面時我也遇到了問題(可能這兩個是相關的)。 如何解決這個問題?

我認為這里的問題是使用redux ..因為只要道具沒有改變,它就會阻止重新渲染組件,

這是因為connect()默認實現了shouldComponentUpdate,假設你的組件在給定相同的props和state的情況下會產生相同的結果。

對此最好的解決方案是確保您的組件是純凈的,並通過道具將任何外部狀態傳遞給它們。 這將確保您的視圖不會重新呈現,除非它們實際需要重新呈現並且將大大加快您的應用程序。

如果由於某種原因這是不實際的(例如,如果你使用的庫嚴重依賴於React上下文),你可以將pure:false選項傳遞給connect():

function mapStateToProps(state) {
  return { todos: state.todos }
}

export default connect(mapStateToProps, null, null, {
  pure: false
})(TodoApp)

這里有更多解釋的鏈接:

react-redux故障排除部分

react-router DOCS

如果使用Redux,則redux connect HOC會覆蓋組件上的shouldComponentUpdate生命周期方法,並檢查道具和狀態更改,這可能會使React Router shouldComponentUpdate困惑。 像用戶單擊鏈接之類的東西不一定會改變狀態或道具,導致不在路由上下文中重新渲染組件。

react路由器的文檔說明了此問題的解決方案:

使用withRouter HOC包裝組件

    import { Route, Switch, withRouter } from 'react-router-dom';
    import { connect } from 'react-redux';

    const Main = (props) => (
    <main>
      <Switch>
        <Route exact path='/' component={SAMPLE_HOME}/>
        <Route path='/dashboard' component={SAMPLE_DASHBOARD}/>    
      </Switch>
    </main>
      )
    export default withRouter(connect()(Main))  

此外,由於封閉路徑組件將使用location屬性傳遞props,您可以將其傳遞給子組件,並且應該實現所需的行為。

https://reacttraining.com/react-router/web/guides/dealing-with-update-blocking

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM