【发布时间】:2019-01-31 17:38:55
【问题描述】:
下面是一个简单的例子:
const { Component } = React
const { render } = ReactDOM
const Label = ({ text }) => (
<p>{text}</p>
)
const Clock = ({ date }) => (
<div>{date.toLocaleTimeString()}</div>
)
class App extends Component {
constructor(props) {
super(props)
this.state = {
date: new Date()
}
}
componentDidMount() {
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.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
this.setState({ date: new Date() }) 每秒被调用一次,用当前时间更新时钟。据我所知,setState 在 App 上调用了 render 方法,这会导致整个组件(包括标签)被重新渲染。
有没有办法在不重新渲染整个 App 组件的情况下将日期传递给 Clock(导致它被重新渲染)?这对性能有多大影响?
【问题讨论】:
-
为 Clock 组件提供自己的内部状态,而不是将其作为父级的 prop 传递。
-
首先不建议在 setTimeout 或 setInterval 中执行 setState
-
调用的渲染函数和实际更改的 DOM 之间存在差异。 react 的全部意义在于它渲染到它的虚拟 DOM 中,然后将其与之前的内容进行比较,并且只更新需要的内容。这称为和解。在您的示例中,标签不会被重新渲染,因为它没有改变,但时钟会。
-
否,默认情况下,如果父级重新渲染所有子级重新渲染。 @ChrisCousins 可能你想告诉时钟组件中不需要 DOM 操作。
-
有一个组件生命周期方法
shouldcomponentupdate,以防您希望停止重新渲染特定组件
标签: javascript reactjs