[英]Rerendering child component when parent state changes in React
I'm still pretty new to React, so I'm sorry if this has a simple answer.我对 React 还是很陌生,所以如果这有一个简单的答案,我很抱歉。 I'm trying to make a bar at the top of the page re-render every time the URL changes (with React Router).
每次 URL 更改(使用 React Router)时,我都试图在页面顶部重新渲染一个栏。 After struggling with this for a while (please let me know if you have any thoughts on an easier solution!), I decided to update the state when a URL changes and pass this new state into a component.
在为此苦苦挣扎了一段时间后(如果您对更简单的解决方案有任何想法,请告诉我!),我决定在 URL 更改时更新状态并将这个新状态传递给组件。 Here is a simplified version of the code:
这是代码的简化版本:
import React from 'react'; import { AppBar, Toolbar, Typography } from '@material-ui/core'; import './TopBar.css'; class TopBar extends React.Component { constructor(props) { super(props); this.state = { url: props.url } this.parseURL = this.parseURL.bind(this); } static getDerivedStateFromProps(props, state) { if (state.url !== props.url) { return { url: props.url } } return null; } render() { return ( <AppBar position="absolute"> <Toolbar> <Typography variant="h5" color="inherit"> {this.state.url} </Typography> </Toolbar> </AppBar> ); } } export default TopBar;
import React from 'react'; import ReactDOM from 'react-dom'; import { HashRouter, Route, Switch } from 'react-router-dom'; import { Grid, Typography, Paper } from '@material-ui/core'; import './styles/main.css'; import TopBar from './components/topBar/TopBar'; import UserDetail from './components/userDetail/userDetail'; import UserPhotos from './components/userPhotos/userPhotos'; class PhotoShare extends React.Component { constructor(props) { super(props); this.state = { url: window.location.href } } render() { return ( <HashRouter> <div> <Grid container spacing={8}> <Grid item xs={12}> <TopBar url={this.state.url} key={this.state} /> </Grid> <Grid item sm={9}> <Paper className="cs142-main-grid-item"> <Switch> <Route path="/users/:userId" render={ props => { this.state.url = props.match.params.userId; console.log(this.state.url); return <UserDetail {...props} key={props.match.params.userId} />;} } /> <Route path="/photos/:userId" render={ props => { this.state.url = props.match.params.userId; console.log(this.state.url); return <UserPhotos {...props} key={props.match.params.userId} />;} } /> </Switch> </Paper> </Grid> </Grid> </div> </HashRouter> ); } } ReactDOM.render( <PhotoShare />, document.getElementById('photoshareapp'), );
The console.log statements when I click a link show that the url state in the PhotoShare component is changing, but the TopBar component is not re-rendering when it changes.单击链接时的 console.log 语句显示 PhotoShare 组件中的 url 状态正在更改,但 TopBar 组件在更改时不会重新渲染。 Is there any way to make sure it re-renders?
有没有办法确保它重新渲染? Thanks for any help!
谢谢你的帮助!
Just a few remarks:简单说几句:
Don't use the state as a key for TopBar
, In the render
of PhotoShare
.不要将状态用作
TopBar
的键,在PhotoShare
的render
中。
React keys should be simple Strings. React 键应该是简单的字符串。
You can simply use "TopBar"
as a key.您可以简单地使用
"TopBar"
作为键。
Anyways it's a single child & a key may not be even required.无论如何,它是一个孩子,甚至可能不需要钥匙。
Don't use props.url
in your TopBar
constructor (leave it null & let getDerivedStateFromProps
do its work.不要在
TopBar
构造函数中使用props.url
(将其保留为 null 并让getDerivedStateFromProps
完成其工作。
I'm wondering if accessing window.location.href
is a side effect.我想知道访问
window.location.href
是否是副作用。 Perhaps, try setState(window.location.href)
inside componentDidMount
instead of initializing it in the constructor itself.也许,尝试
setState(window.location.href)
在componentDidMount
中,而不是在构造函数本身中初始化它。
Never set state using this.state.foo =
.永远不要使用
this.state.foo =
设置状态。 The setState
method should be used instead.应该改用
setState
方法。 Not sure about React router, but you cannot update state anyways inside a render
method.不确定 React 路由器,但无论如何您都无法在
render
方法中更新状态。
See Detect Route Change with react-router for a better solution.请参阅Detect Route Change with react-router以获得更好的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.