简体   繁体   English

当 React 中的父状态发生变化时重新渲染子组件

[英]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的键,在PhotoSharerender中。
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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM