React初识(3-16)

setState()说明

setState更新数据时异步的,如果想多个setState进行依赖,需要将setState修改成传一个回调函数的形式(不过用到的情况很少)
第二个参数
在状态更新后立即执行某个操作
语法:

class Parent extends React.Component {
    state = {
        count: 0
    }

    handClick = () => {
        // 当多次调用setState时推荐写成
        this.setState((state, props) => {
            return state.count = state.count + 1
        },() => {
            // 
            console.log('setState回调函数打印  ' + this.state.count)
        })
        console.log('setState后打印  ' + this.state.count)
    }

    render () {
        return <div>{this.state.count}<button onClick={this.handClick}>+1</button></div>
    }
}


class App extends React.Component {
    // 通过render组合来使用Mouse组件传递过来的值
    render () {
        return <div>
            <Parent />
        </div>
    }
}

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

JSX语法转化过程

JSX仅仅是createElement()方法的语法糖(简化语法)
JSX语法被@babel/preset-react插件编译为createElement()方法
而后又被转化为React对象

JSX语法 =》 createElement() => React元素

组件更新机制

setState()的两个作用:
1.修改state
2.更新组件(UI)
过程:父组件更新渲染时,也会重新渲染子组件。但是只会渲染当前节点树的子树,也就是父组件重新渲染时,所有子组件的render会重新渲染,但是render重新执行不代表页面会重新渲染,render这个重新执行并不一定会渲染页面

组件性能优化

1. 减轻state

减轻state: 只存储跟组件渲染相关的数据
注意:不要做渲染的数据不要放在state中,比如定时器id等
对于这种需要在多个方法中用到的数据,

2. 避免不需要的重新渲染

组件更新机制:父组件更新会引起子组件没有任何变化时也会重新渲染
注意:使用钩子函数shouldComponentUpdate(newProps, nextState)
作用: 通过返回值决定该组件是否重新渲染,返回true表示重新渲染,false表示补充性渲染
该钩子函数可以获得两个参数
newProps:最新的props值
newState:最新的state的值
执行时机:更新阶段的钩子函数,组件重新渲染前执行

class Parent extends React.Component {
    state = {
        count: 0
    }

    handClick = () => {
        this.setState({
            count: this.state.count + 1
        })
    }

    render () {
        return <div>{this.state.count}<button onClick={this.handClick}>+1</button><Child /></div>
    }
}

class Child extends React.Component  {
    // 钩子函数
    shouldComponentUpdate (nextProps, nextState) {
        // 返回false组件不更新,返回true组件更新
        return false
    }
    render () {
        console.log('执行了子组件的render')
        return <div>子组件</div>
    }
}

class App extends React.Component {
    // 通过render组合来使用Mouse组件传递过来的值
    render () {
        return <div>
            <Parent />
        </div>
    }
}

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

子组件避免重新渲染

class Parent extends React.Component {
    state = {
        count: 0
    }

    handClick = () => {
        // 随机生成一个数[0,3)
        this.setState({
            count: Math.floor(Math.random() * 3)
        })
    }

    render () {
        return <div><button onClick={this.handClick}>+1</button><Child {...this.state}/></div>
    }
}

class Child extends React.Component  {
    // 钩子函数
    shouldComponentUpdate (nextProps, nextState) {
        // 返回false组件不更新,返回true组件更新
        // 如果上一次和这次的值相同则不更新组件
        if(nextProps.count === this.props.count) return false
        return true
    }
    render () {
        console.log('执行了子组件的render')
        return <div>子组件:{this.props.count}</div>
    }
}

class App extends React.Component {
    // 通过render组合来使用Mouse组件传递过来的值
    render () {
        return <div>
            <Parent />
        </div>
    }
}

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

纯组件

纯组件:PureComponent与React.Component的功能相似
区别:PureComponent内部自动实现了shouldComponentUpdate钩子,不需要手动比较
原理:纯祖键内部通过分别比对前后两次props和state的值,来决定是否重新渲染组件
说明:纯组件内部的对比是shallow compare(浅层对比)
对于值类型来说:比较两个值是否相同
对于引用类型来说:只比较对象的引用(地址)是否相同

class Parent extends React.Component {
    state = {
        count: 0
    }

    handClick = () => {
        // 随机生成一个数
        this.setState({
            count: Math.floor(Math.random() * 3)
        })
    }

    render () {
        return <div><button onClick={this.handClick}>+1</button><Child {...this.state}/></div>
    }
}

// 创建一个纯组件
class Child extends React.PureComponent  {
    render () {
        console.log('执行了子组件的render')
        return <div>子组件:{this.props.count}</div>
    }
}

class App extends React.Component {
    // 通过render组合来使用Mouse组件传递过来的值
    render () {
        return <div>
            <Parent />
        </div>
    }
}

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

虚拟DOM和Diff算法

虚拟DOM:本质上就是一个JS对象,用来描述你希望在屏幕上看到的内容(UI)
组件render()调用后,根据状态和JSX结构生成虚拟DOM对象
如:

// 虚拟dom示例(但并不是)
const element = {
	type: 'h1',
	props: {
		className: 'greeting',
		children: 'Hello JSX'
	}
}

执行过程:
1.初次渲染时,React会根据厨师state(Model),创建一个虚拟DOM对象(数)。
2.根据虚拟DOM生成真正的DOM,渲染到页面中
3.当数据变化后(setState()),重新根据新的数据,创建新的虚拟DOM对象(树)
4.与上一次得到的虚拟DOM对象,使用Diff算法对比(找不同),得到需要更新的内容
5.最终,React值将变化的内容更新到DOM中,重新渲染到页面
diff算法比对:tree diff、component diff、element diff

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值