(React学习笔记2)setState知识点总结

198 阅读2分钟

(React学习笔记2)setState知识点总结

1.state定义

类组件中:state需要在构造函数中定义

class App extends React.Component {
    
    constructor(props) {
        super(props)
        this.state = {
          count: 1
    	}
    }
    
}

2.修改state----不可变值(重点!!!)

不能够直接修改state,需要通过this.setState()

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

修改state数组或者对象需要使用纯函数(输出是数组;无副作用)

  1. 常见数组修改方式
this.setState({
    list: this.state.list.concat(10),
    list1: this.state.list.slice(1,3),
    list2: this.state.list.filter(item => return item > 10),
    list3: [...this.state.list, 10]    
})
  1. 常见对象修改形式
this.setState({
    obj: {...this.state.obj1, name: 'xxx'},
    obj1: Object.assign({}, this.state.obj1, {a: 100})
})

注意:一定不能够使用push,pop,splice操作,原因他们含有副作用,会对原函数造成影响。还会影响React组件的更新问题(比较绕尝试尽力表达清楚)

this.state.list.push(10)
this.setState({
    list: this.state.list // 前后list是一样的
})

shouldComponentUpdate(nextProps, nextState) {
    if (nextPorps.list===this.props.list) {
        // 数据改变,触发重新渲染
        return true
    }
    // 无变换,不更新组件
    return false
}

如果使用this.state.list.push(10)之后,原state数值已经变化,再调用shouldComponentUpdate就直接认定前后组件数据是没有发生变化,就不会触发组件更新,产生了bug。

3.setState异步

  1. setState正常使用时候是异步

    this.setState({
       count: this.state.count + 1 // 页面显示每次加一
    })
    console.log('count', this.state.count); // 打印是原state值
    
    // 通过回调函数可以拿到修改后state值
    this.setState( {
       count: this.state.count + 1
    }, () => {
       console.log('callback', this.state.count);
    })
    

    多个setState才做放在一起会合并为一个操作,DOM只会显示+1。

    原因:异步。三个setState拿到的count都为0

    this.setState({
      count: this.state.count + 1
    })
    this.setState({
      count: this.state.count + 1
    })
    this.setState({
      count: this.state.count + 1
    })
    
  2. 放在setTImeout或者DOM事件回调函数中使用,变成同步

    // setTimeout回调函数
    setTimeout(() => {
      this.setState({
        count: this.state.count + 1
      })
      console.log(this.state.count);
    }, 0)
    
    //  自定义DOM事件--记得及时销毁事件
    bodyClickHandler = () => {
      setTimeout(() => {
        this.setState({
          count: this.state.count + 1
        })
        console.log(this.state.count);
      }, 0)
    }
    componentDidMount() {
      document.body.addEventListener('click', this.bodyClickHandler)
    
  3. 函数形式--使用函数形式,多个操作不会有合并问题

    this.setState((prevState, props) => {
      return {
        count: prevState.count + 1
      }
    })
    this.setState((prevState, props) => {
      return {
        count: prevState.count + 1
      }
    })
    this.setState((prevState, props) => {
      return {
        count: prevState.count + 1
      }
    })