React setState使用与深入理解

setState作用更改数据,重新渲染页面,直接进行更改数据,值会更新,但页面不会重新渲染

如不使用setState更改数据,则可以使用foceUpdate强制渲染页面

setState与foceUpdate区别:

相同点:

  • 都是重新渲染页面

不同点:

  • setState执行流程:先走shouldComponentUpdate=>ComponentWillUpdate
  • 使用setState后,如不使用shouldComponentUpdate则即使没有更改数据也会重新渲染组件
  • foceUpdate执行流程:直接走ComponentWillUpdate

setState知识点(重点):

  1. setState执行后,会调用shouldComponentUpdate在执行ComponentWillUpdate,在shouldComponentUpdate可以判断是否数据更改 从而来决定是否要重新渲染组件,如进行判断则每次setState都将会重新渲染组件(包括自组件)
  2. setState在执行时会把所有要更改的,合成一次后进行重新渲染  
  3. setState执行中如遇到相同内容更改,则会执行最后一个,前面相同的不执行
  4. setState属于异步情况下:在合成事件或者生命周期函数中都是异步操作
  5. setState属于同步情况下:在一个异步事件中执行(例如定时器)则setState将会是同步执行

直接更改,将不会重新渲染页面,例子如下:

import React from 'react'
export default class ChangeVal extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            title: '更改数据'
        }
    }
    render() {
        return (
            
{this.state.title}
) } componentDidMount() { this.state.title = '更改了数据' console.log(this.state.title) //更改了数据 但是视图没有更新 } }

foceUpdate强制更新页面 

import React from 'react'
export default class ChangeVal extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            title: '更改数据'
        }
    }
    render() {
        return (
            
{this.state.title}
) } componentDidMount() { this.state.title = '更改了数据' console.log(this.state.title) //更改了数据 但是视图没有更新 this.forceUpdate() //不使用this.setState强制更新 } }

使用setState更改(推荐)

import React from 'react'
export default class ChangeVal extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            title: '更改数据'
        }
    }
    render() {
        return (
            
{this.state.title}
) } componentDidMount() { this.setState({ title:'更改了数据' }) } }

setState更改 (函数式更改)

import React from 'react'
export default class ChangeVal extends React.Component {
    constructor(props) {
        super(props)
       this.setState((val) => {
            console.log(val)//{num:0}
			{num: 2}
        })
      //this.setState((state, props) => ({
  			//num: 2
	  //}));
        
       //this.setState(function(state, props) {
  			//return {
    		//	num: 2
  			//};
		//});
    }
    render() {
        return (
            
{this.state.title}
) } componentDidMount() { this.setState({ title:'更改了数据' }) } }

当点击按钮父组件只要执行了setState即使没有更改任何值,但父组件和子组件还是重新渲染

import React from 'react'
export default class SetStateDemo extends React.Component {
    state = {
        num: 0
    };
    handle = () => {
        let { num } = this.state
        this.setState({
        })
    }
    render() {
        console.log('是否更新')
        let { num } = this.state
        return (
            
        )
    }
}
class Small extends React.Component {
    render() {
        console.log('子组件是否重新更新')
        return (
            
) } }

解决 this.setState不需要重新渲染 setState没有更改值则父组件和子组件都不会重新渲染    shouldComponentUpdate

import React from 'react'
export default class SetStateDemo extends React.Component {
    state = {
        num: 0
    };
    handle = () => {
        let { num } = this.state
        this.setState({
        })
    }
    render() {
        console.log('是否更新')
        let { num } = this.state
        return (
            
        )
    }
    //不进行重新渲染
    shouldComponentUpdate(nextProps, nextState) {
        if (nextState.num === this.state.num) { return false } return true
    }
}
class Small extends React.Component {
    render() {
        console.log('子组件是否重新更新')
        return (
            
) } }

setState执行的顺序

  1. 先执行SetStateDemo2 ==> render  console.log('b')
  2. setState异步 所以先执行   console.log('a')
  3. componentDidMount  setState更改后再次执行 1
  4. 最后执行setState回调函数的  console.log(2)
import React from 'react'
export default class SetStateDemo2 extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            title: 'setState异步问题'
        }
    }
    render() {
        console.log('b') //第一个执行  
        return (
            
{this.state.title}
) } componentDidMount() { this.setState({ title: '更改了数据' }, () => { console.log(2) //最后执行 }) console.log('a')//第二个执行 } }

setState同步异步问题

  1. setState在合成事件或者生命周期函数中都是异步操作
  2. setState在执行时会把其中所有要更改的,合成一次后进行重新渲染    
  3. 如果修改的状态都是一样的,则以最后一次为主
  4. setState在一个异步事件中执行(例如定时器)则setState将会是同步执行
import React from 'react'
export default class ChangeVal2 extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            number: 0,
            number2: 0
        }
    }
    render() {
        return (
            
{this.state.number}{this.state.number2}
) } funchange = ev => { /* setState中执行多次一样的 但是只会执行一次,因为它会一样的合并并且执行最后一次 */ this.setState({ number: this.state.number + 1, number2: this.state.number2 + 1, number2: this.state.number2 + 1 }) /* 对应第一条异步:点击后页面+1了数据 但是打印还是+1之前的数据。 例如数据默认值是0 点击增加后页面显示1 但这里打印实际还是0 表明了setState是异步的 */ console.log(this.state.number) } /* 把setState 放到一个异步操作中,就没有必要异步了,就变成了同步 */ componentDidMount() { setTimeout(() => { this.setState({ number: this.state.number + 1, number2: this.state.number2 + 1, number2: this.state.number2 + 1 //对应第三条 修改状态一样,则以最后一次为主 }) console.log(this.state) //默认是0 加1后页面显示1 这里也显示1 则表明当前setState是同步的 }, 1000) } }

你可能感兴趣的:(react,reactjs,react.js)