第五节:state和setState

328 阅读1分钟

state

state: 在写代码的时候要分析哪些数据是组件自身的

class Title extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div>{ this.props.title }</div>
    )
  }
}

class DateTime extends React.Component {
  constructor(props) {
    super(props);
    this.t = null;
  }
  state = {
    dataTime: new Date().toString()
  }
  // 挂载到真实dom后执行
  componentDidMount() {
    this.t = setInterval(() => {
      this.setState({
        dataTime:  new Date().toString()
      })
    }, 1000)
  }
  // 组件即将被卸载前
  componentDidMount() {
    // 清楚定时器
    clearInterval(this.t);
    this.t = null;//释放空间
  }
  render() {
    return (
      <h2 id="date-time">It's Now { this.state.dataTime }</h2>
    )
  }
}

class Board extends React.Component {
  render() {
    return (
      <div>
        <Title title="hello react"/>
        <DateTime />
      </div>
    )
  }
}

ReactDOM.render(
  <Board />,
  document.getElementById('app')
)

// 卸载组件
setTimeout(() => {
  ReactDOM.unmountComponentAtNode(
    document.getElementById('app')
  );
}, 5000)

总结:

1.如果想使用组件的时候,传入数据 - props 组件配置

  1. 如果是组件内部使用的数据 - state 私有数据 (状态)
  1. state 使用的注意事项
  • 必须使用setState 方法来更改state
  • 多个setState 是会合并调用的
  1. props 和state更新数据要谨慎 → 尽量避免直接依赖他们(很有可能是在异步程序中更新的)
  • 可能导致数据不对 → 如下操作
this.setState({
  t: this.state.t + this.props.content//=> 避免这种操作
})
  • 多个setState 是会合并调用的解决方法如下 → 回调函数的形式
    • 有2个方法参数,第一个写逻辑, 第二个在处理完成后的回调
this.setState((state, props) => ({
   //=> state 是上一个state
   //=> props 是此次更新时被使用props
   t: state.t + props.content 
}))

setState简单的原理实现

let state = {num: 0}
let callbacks = []
callbacks.push([(state => ({num: state.num + 1}), () => {console.log(state)})])//6
callbacks.push([(state => ({num: state.num + 2}), () => {console.log(state)})])//6
callbacks.push([(state => ({num: state.num + 3}), () => {console.log(state)})])//6

let cb
let fns = []
while(v = callbacks.shift()) {
    const [cb, fn] = v
    state = cb(state)
    fns.push(fn)
}

fns.forEach(fn => fns)

5.setState 操作合并的原理 → 是浅合并 Object.assign(this.state, num: this.state.num + 1)

  • → 操作用扩展运算符(推荐)
let arr = [1,2,3]
/****/
this.setState({
  arr: [...arr, 4]
})