美文网首页
React - 组件、父子组件的setState、constru

React - 组件、父子组件的setState、constru

作者: 闪电西兰花 | 来源:发表于2020-07-11 17:01 被阅读0次
    结论:组件 render 的触发条件
    1. 首次加载组件
    2. setState 改变组件内部的 state,父组件的 state 改变也会触发子组件的 render
    3. 接收的 props 发生改变
    • 观察单个组件 setState 对组件 render 的影响
      • 首先要明确组件的 setState 是会让组件执行 render 的,并且因为React在开发环境中使用了严格模式(见下面代码),组件的 constructorrender 都各自执行了2遍,然后我们区分2种情况:(严格模式可参考 React 严格模式
        1. 在一个生命周期内同时执行2次 setState
        2. 在一个生命周期内,执行2次 setState,第2次用setTimeout 延时执行
      • 从打印的结果图片可以看出,同时执行 setState 的,因为 setState 而触发组件 render只会执行1次,因为react会将多次 setState 排进队列里合并执行,也就是如果在 setState中多次累加同一个变量值但最后也只会执行1次;而延时执行 setState是会因此而继续触发 render
    ReactDOM.render(
      <React.StrictMode>
        <App />
      </React.StrictMode>,
      document.getElementById('root')
    );
    
    // App.js
    import React from 'react';
    import './App.css';
    
    class App extends React.Component {
    
      constructor (props) {
        console.log('App constructor')
        super(props);
        this.state = {
          lifeProp: 'this is life prop',
          list: []
        }
      }
    
    
      // 1. 在一个组件中同时setState不同的2个变量
      componentDidMount () {
        this.setState({lifeProp: 'a new prop'})
        this.setState({list: [1,2,3]})
      }
    
     // 2. 在一个组件中延时setState第2个变量
      componentDidMount () {
        this.setState({lifeProp: 'a new prop'})
        setTimeout(() => {
          this.setState({list: [1,2,3]})
        }, 2000)
      }
    
      render () {
        console.log('App render')
        return (
          <div className="App">
            {/* 容器组件 */}
            <CommentList></CommentList>
          </div>
        );
      }
    }
    
    export default App;
    
    一个组件中同时执行setState2次修改2个变量.jpg
    一个组件延时修改第2个变量.jpg
    • 观察父子组件 setState 对组件 render 的影响
      1. 首先使用最基本的父子组件配置,组件各自都只有基本的 constructorstaterender,然后分别在组件中打印出各自的 constructorrender的执行情况
    // 父组件 App.js
    import React from 'react';
    import './App.css';
    import {CommentList} from './components/CommentList'
    
    class App extends React.Component {
    
      constructor (props) {
        console.log('App constructor')
        super(props);
        this.state = {
          lifeProp: 'this is life prop',
          list: []
        }
      }
    
      render () {
        console.log('App render')
        return (
          <div className="App">
            {/* 容器组件 */}
            <CommentList></CommentList>
          </div>
        )
      }
    }
    
    export default App;
    
    // 子组件 CommentList.js
    import React from 'react'
    
    export class CommentList extends React.Component {
      constructor(props) {
        console.log('CommentList constructor')
        super(props)
        this.state = {
          comments: [],
          tempData: '12345'
        }
      }
    
      render () {
        console.log('CommentList render')
        return (
          <div></div>
        )
      }
    }
    
    基本配置父子组件.jpg
    1. 再看第二种情况,由单个组件中 setStaterender 的影响我们可以推测出,当父组件 setState 时,触发了父组件的 render ,从而也触发子组件的 render,下面可以验证一下,下面是对组件的修改和结果:
      // App.js
      componentDidMount () {
        this.setState({lifeProp: 'a new prop'})
        setTimeout(() => {
          this.setState({list: [1,2,3]})
        }, 2000)
      }
    
    父组件setState对子组件的影响.jpg
    1. 第三种情况,我们了解下父组件向子组件传值的时候,父组件修改了传的值,对子组件的影响,本次修改结果同上
    // App.js
     componentDidMount () {
       this.setState({lifeProp: 'a new prop'})
       setTimeout(() => {
         this.setState({list: [1,2,3]})
       }, 2000)
     }
    
    // 将值传给子组件
     <CommentList title={this.state.lifeProp}></CommentList>
    
    // CommentList.js
    // 在子组件接受父组件的传值
      render () {
        console.log('CommentList render')
        return (
          <div>
            {this.props.title}
          </div>
        )
      }
    

    相关文章

      网友评论

          本文标题:React - 组件、父子组件的setState、constru

          本文链接:https://www.haomeiwen.com/subject/xnkaqktx.html