使用 React Router 更改路线时导航栏组件位置不会更新
Navbar component location doesn't update when route changed, with React Router
我正在用 React 构建一个应用程序,并试图在用户导航到其他页面时更新导航栏。但是检测location prop的变化是不一致的
如果我进入主页并刷新页面,然后单击帐户 link,帐户和导航栏 location.pathname 属性都从“/”变为 "Account",正如预期的那样,控制台正确写入 "change".
如果我随后单击“主页”link,导航栏将再次正确检测到路线更改。
但是,如果我现在再次单击 "Account",导航栏的位置不会更新,它仍然是“/”并且未检测到更改。
我看不出这两种情况有什么不同,但我第一次单击 "Account" 时它始终有效,而不是第二次。
我已经阅读了关于 blocking components 的 React Router 文档,但我不认为这是问题所在,因为导航栏是顶级组件,我使用 'location' 作为道具,我没有使用 purecomponent,Account 组件确实更新了。而且我认为如果这是问题所在,它永远不会起作用?
有人可以建议我如何让导航栏始终检测路线何时发生变化吗?谢谢!
Navbar.js:
class Navbar extends Component {
constructor(props) {
super(props);
}
componentDidUpdate = (prevProps) => {
console.log('***');
console.log('nav old pathname', prevProps.location.pathname);
console.log('nav new pathname', this.props.location.pathname);
if (prevProps.location.pathname !== this.props.location.pathname) {
// this usually doesn't trigger on navigate
console.log('change');
}
}
render() {
...render my html
}
}
export default connect(mapStateToProps)(withRouter(Navbar));
App.js:
const App = () => (
<Provider store={store}>
<Router>
<div>
<Navbar />
<div className="container">
<Route exact path="/" component={Home} />
<Route exact path="/account" component={Account} />
</div>
</div>
</Router>
</Provider>
);
export default App;
来自 package.json:
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.18",
"@fortawesome/free-regular-svg-icons": "^5.8.2",
"@fortawesome/free-solid-svg-icons": "^5.8.2",
"@fortawesome/react-fontawesome": "^0.1.4",
"bootstrap": "^4.2.1",
"classnames": "^2.2.6",
"formik": "^1.5.7",
"i": "^0.3.6",
"jquery": "^3.4.0",
"jwt-decode": "^2.2.0",
"normalizr": "^3.3.0",
"npm": "^6.9.0",
"prop-types": "^15.7.2",
"react": "^16.8.2",
"react-dom": "^16.8.2",
"react-markdown": "^4.0.6",
"react-redux": "^6.0.0",
"react-router-dom": "^4.3.1",
"react-scripts": "3.0.0",
"react-widgets": "^4.4.11",
"reactstrap": "^7.1.0",
"redux": "^4.0.1",
"redux-devtools-extension": "^2.13.8",
"redux-thunk": "^2.3.0",
"reselect": "^4.0.0",
"updeep": "^1.1.0"
},
import Switch from react-router-dom to your App.js
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
const App = () => (
<Provider store={store}>
<Router>
<div>
<Navbar />
<div className="container">
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/account" component={Account} />
</Switch>
</div>
</div>
</Router>
</Provider>
);
export default App;
don't forget to import Navbar, Home, and Account
问题出在这一行:
export default connect(mapStateToProps)(withRouter(Navbar));
您没有使用 PureComponent
,但 redux connect
是。您可以通过以下方式解决此问题:
1.Invert 组成:
export default withRouter(connect(mapStateToProps)(Navbar));
2.Pass location props down in mapStateToProps
:
const mapStateToProps(state, ownProps) {
return {
location: ownProps.location
}
}
我正在用 React 构建一个应用程序,并试图在用户导航到其他页面时更新导航栏。但是检测location prop的变化是不一致的
如果我进入主页并刷新页面,然后单击帐户 link,帐户和导航栏 location.pathname 属性都从“/”变为 "Account",正如预期的那样,控制台正确写入 "change".
如果我随后单击“主页”link,导航栏将再次正确检测到路线更改。
但是,如果我现在再次单击 "Account",导航栏的位置不会更新,它仍然是“/”并且未检测到更改。
我看不出这两种情况有什么不同,但我第一次单击 "Account" 时它始终有效,而不是第二次。
我已经阅读了关于 blocking components 的 React Router 文档,但我不认为这是问题所在,因为导航栏是顶级组件,我使用 'location' 作为道具,我没有使用 purecomponent,Account 组件确实更新了。而且我认为如果这是问题所在,它永远不会起作用?
有人可以建议我如何让导航栏始终检测路线何时发生变化吗?谢谢!
Navbar.js:
class Navbar extends Component {
constructor(props) {
super(props);
}
componentDidUpdate = (prevProps) => {
console.log('***');
console.log('nav old pathname', prevProps.location.pathname);
console.log('nav new pathname', this.props.location.pathname);
if (prevProps.location.pathname !== this.props.location.pathname) {
// this usually doesn't trigger on navigate
console.log('change');
}
}
render() {
...render my html
}
}
export default connect(mapStateToProps)(withRouter(Navbar));
App.js:
const App = () => (
<Provider store={store}>
<Router>
<div>
<Navbar />
<div className="container">
<Route exact path="/" component={Home} />
<Route exact path="/account" component={Account} />
</div>
</div>
</Router>
</Provider>
);
export default App;
来自 package.json:
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.18",
"@fortawesome/free-regular-svg-icons": "^5.8.2",
"@fortawesome/free-solid-svg-icons": "^5.8.2",
"@fortawesome/react-fontawesome": "^0.1.4",
"bootstrap": "^4.2.1",
"classnames": "^2.2.6",
"formik": "^1.5.7",
"i": "^0.3.6",
"jquery": "^3.4.0",
"jwt-decode": "^2.2.0",
"normalizr": "^3.3.0",
"npm": "^6.9.0",
"prop-types": "^15.7.2",
"react": "^16.8.2",
"react-dom": "^16.8.2",
"react-markdown": "^4.0.6",
"react-redux": "^6.0.0",
"react-router-dom": "^4.3.1",
"react-scripts": "3.0.0",
"react-widgets": "^4.4.11",
"reactstrap": "^7.1.0",
"redux": "^4.0.1",
"redux-devtools-extension": "^2.13.8",
"redux-thunk": "^2.3.0",
"reselect": "^4.0.0",
"updeep": "^1.1.0"
},
import Switch from react-router-dom to your App.js
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
const App = () => (
<Provider store={store}>
<Router>
<div>
<Navbar />
<div className="container">
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/account" component={Account} />
</Switch>
</div>
</div>
</Router>
</Provider>
);
export default App;
don't forget to import Navbar, Home, and Account
问题出在这一行:
export default connect(mapStateToProps)(withRouter(Navbar));
您没有使用 PureComponent
,但 redux connect
是。您可以通过以下方式解决此问题:
1.Invert 组成:
export default withRouter(connect(mapStateToProps)(Navbar));
2.Pass location props down in mapStateToProps
:
const mapStateToProps(state, ownProps) {
return {
location: ownProps.location
}
}