以下是一个简单的例子:
const { Component } = React
const { render } = ReactDOM
const Label = ({text}) => (<p>{text}</p>)
const Clock = ({ date }) => (
<div>{date.toLocaleTimeString()}</div>
)
class App extends Component {
constructor() {
super()
this.state = {
date: new Date()
}
}
componentWillMount() {
this.interval = setInterval(
() => this.setState({ date: new Date() }),
1000
)
}
componentWillUnmount() {
clearInterval(this.interval)
}
updateTime() {
}
render() {
return (
<div>
<Label text="The current time is:" />
<Clock date={this.state.date} />
</div>
)
}
}
render(<App />, document.querySelector('#app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
这是一个指向codepen的链接:
https://codepen.io/mytee306/pen/yxezEy
每秒使用当前时间更新Clock时调用this.setState({date:new Date()}) . 据我所知,setState调用App上的render方法,导致整个组件被重新呈现,包括Label .
有没有办法将日期传递给Clock(导致它被重新渲染)而不重新渲染整个App组件?这在性能方面发挥了多大的作用?
1 回答
你想要的不可能 . 要将prop传递给子组件,父组件的状态或道具应该以某种方式改变 . 如你所知,这显然会触发重新渲染,因此所有的孩子都会重新渲染 . 要进行更新,应在此情况下重新呈现和卸载/重新安装
Clock
组件以反映DOM更改 .如果您的应用程序不是那么大并且没有这么多孩子,那么就不要为这个问题而烦恼,因为渲染不是那么昂贵 . 昂贵的是组件的DOM操作 . 在这里,React区分真实和虚拟DOM,即使重新渲染,也不会卸载/重新安装
Label
组件 . 但是,如果您将Label
组件编写为PureComponent
,则不会重新渲染 . 但是要像这样更新Clock
组件,没有办法 .