下面是一个简单的例子:
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'))
个字符this.setState({ date: new Date() })
每秒被调用一次,用当前时间更新时钟。据我所知,setState
调用App上的render方法,导致整个组件重新渲染,包括Label。
有没有一种方法可以将日期传递给时钟(导致它被重新渲染),而不需要重新渲染整个应用程序组件?这对性能有多大影响?
4条答案
按热度按时间2ledvvac1#
如果要更新子项而不更新父项,则状态必须在子项中。你可以将状态getter / setter从子对象传递给父对象,以便能够读取和更新它:
字符串
由于
const [value, setValue] = useState(0);
位于Child
中,因此在更新值时,只有子组件将重新呈现。此外,由于Parent
在onChildMount
接收value
和setValue
,因此父节点可以使用它们来更新子节点,而无需重新呈现父节点。vzgqcmou2#
你想要的不可能。要将prop传递给子组件,父组件的状态或prop应该以某种方式更改。如你所知,这显然会触发一个重新渲染,所以所有的子元素都会重新渲染。要进行更新,您的
Clock
组件应该在这种情况下重新呈现和卸载/重新装载,以反映DOM更改。如果你的应用程序不是很大,也没有那么多的子程序,那么就不要纠结这个问题,因为渲染并不那么昂贵。代价最高的是组件的DOM操作。在这里,React区分了真实的和虚拟DOM,并且即使重新渲染也不会卸载/重新装载
Label
组件。但是,如果您将Label
组件编写为PureComponent
,则不会重新呈现。但是对于像这样更新Clock
组件,没有办法。字符串
p5cysglq3#
使用子组件的参考,可以实现:
字符串
g2ieeal74#
使用
useImperativeHandle
和React.forwardRef
,您可以将状态从Child返回到Parent作为ref:字符串