携手并肩写作,一起成长!

lxf2023-03-10 16:57:01

携手并肩写作,一起成长!这个是我参加「AdminJS日新的目标 · 8 月更文考验」第25天,查看更多活动规则

序言

我们都知道 React 部件是由 setState() 方式来同步数据的。因此在一个模块中,在我们启用 setState() 方式便会升级 state,而且能把系统重装后的 state 再次3D渲染到页面上,这不难理解,但如果存有好几个相关的部件时,假如其中一个元件的 setState() 方式被启用,会有什么?

剖析

比如有如下编码:

// 导进ract
import React from 'react'
import ReactDOM from 'react-dom'

// App部件
class App extends React.Component {
  state = {
    num: 0,
  }

  handleClick = () => {
    this.setState(state => ({ num: state.num   1 }))
  }

  render() {
    console.log('App部件被启用')
    return (
      <div className='app' style={{ backgroundColor: '#00c9ff', padding: '20px' }}>
        <h1>App元件的num:{this.state.num}</h1>
        <button onClick={this.handleClick} style={{ marginBottom: '10px' }}>点此 1</button>
        <div className='app-wrapper' style={{ width: '100%', display: 'flex', justifyContent: 'center' }}>
          <Son1 />
          <Son2 />
        </div>
      </div>
    )
  }
}

class Son1 extends React.Component {
  state = {
    num: 0
  }

  handleClick = () => {
    this.setState(state => ({ num: state.num   1 }))
  }

  render() {
    console.log('部件1被启用')
    return (
      <div className='parent1' style={{ backgroundColor: '#2196f3', width: '50%', padding: '20px', marginRight: '20px' }}>
        <h2>部件1的num:{this.state.num}</h2>
        <button onClick={this.handleClick} style={{ marginBottom: '10px' }}>点此 1</button>
        <div className='parent1-wrapper' style={{ width: '100%', display: 'flex', justifyContent: 'center' }}>
          <Child11 />
          <Child12 />
        </div>
      </div>
    )
  }
}

class Child11 extends React.Component {
  render() {
    console.log('部件1-1被启用')
    return (
      <div className='child11' style={{ backgroundColor: '#ffeb3b', height: '300px', width: '50%', marginRight: '20px' }}>
        部件1-1
      </div>
    )
  }
}

class Child12 extends React.Component {
  render() {
    console.log('部件1-2被启用')
    return (
      <div className='child12' style={{ backgroundColor: '#ffeb3b', height: '300px', width: '50%' }}>
        部件1-2
      </div>
    )
  }
}

class Son2 extends React.Component {
  state = {
    num: 0
  }

  handleClick = () => {
    this.setState(state => ({ num: state.num   1 }))
  }

  render() {
    console.log('部件2被启用')
    return (
      <div className='parent2' style={{ backgroundColor: '#2196f3', width: '50%', padding: '20px' }}>
        <h2>部件2的count:{this.state.num}</h2>
        <button onClick={this.handleClick} style={{ marginBottom: '10px' }}>点此 1</button>
        <div className='parent2-wrapper' style={{ width: '100%', display: 'flex', justifyContent: 'center' }}>
          <Child21 />
          <Child22 />
        </div>
      </div>
    )
  }
}

class Child21 extends React.Component {
  render() {
    console.log('部件2-1被启用')
    return (
      <div className='child21' style={{ backgroundColor: '#ffeb3b', height: '300px', width: '50%', marginRight: '20px' }}>
        部件2-1
      </div>
    )
  }
}

class Child22 extends React.Component {
  render() {
    console.log('部件2-2被启用')
    return (
      <div className='child22' style={{ backgroundColor: '#ffeb3b', height: '300px', width: '50%' }}>
        部件2-2
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('root'))

其页面渲染实际效果如下所示:

携手并肩写作,一起成长!

其关系网如下所示:

携手并肩写作,一起成长!

在我点一下“部件1”里的按键时控制面板打印出如下所示:

携手并肩写作,一起成长!

通过对比可以得出下列结果:

  • 假如部件1里的 setState() 方式被启用,部件1自身以及子组件1-1和子组件1-2将重新营造了
  • 父部件App,哥们部件2,哥们部件2的子组件2-1及子组件2-2并没再次3D渲染

这表明当某一部件再次3D渲染时,其下边的部件树还会再次3D渲染,但该元件的父部件及哥们部件树并不是会受到影响。我们通过下边的实际操作来验证该观点。

点一下“部件2”里的按键结论如图所示:

携手并肩写作,一起成长!

点一下App部件里的按键结论如图所示:

携手并肩写作,一起成长!

之上全过程展现出来的便是 React 元件的升级体制。