小编典典

React:更新子组件而不渲染父组件

reactjs

以下是一个简单的示例:

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() })被每秒调用一次,以当前时间更新Clock。据我所知,setState在App上调用render方法将导致整个组件(包括Label)重新呈现。

有没有一种方法可以将日期传递给Clock(使其重新呈现)而又不重新呈现整个App组件?这在性能方面起着多大的作用?


阅读 355

收藏
2020-07-22

共1个答案

小编典典

您不可能想要什么。要将prop传递给子组件,父组件的状态或prop应该以某种方式更改。如您所知,这显然会触发重新渲染,因此所有子级都将重新渲染。要进行更新,Clock在这种情况下应重新渲染和卸载/重新安装您的组件以反映DOM更改。

如果您的应用程序不是很大,并且没有那么多的子代,则不必担心此问题,因为渲染并不那么昂贵。昂贵的一个是组件的DOM操作。在这里,React会扩散实际和虚拟DOM,Label即使重新渲染也不会卸载/重新安装组件。但是,如果您将Label组件编写为PureComponent,则不会重新渲染。但是要Clock像这样更新组件,是没有办法的。

class Label extends React.PureComponent {
  render() {
    console.log("rendered");
    return (<p>{this.props.text}</p>)
  }
}

const Clock = ({ date }) => (
  <div>{date.toLocaleTimeString()}</div>
)

class App extends React.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>
    )
  }

}
2020-07-22