react状态管理及事件机制学习笔记

64 阅读2分钟

React - createReactClass(知道)

  • React.createClass({}) 方式,创建有状态组件,该方式已经被废弃!!!
  • 通过导入 require('create-react-class'),可以在不适用 ES6 的情况下,创建有状态组件
  • getDefaultProps() 和 getInitialState() 方法:是 createReactClass() 方式创建组件中的两个函数
  • React without ES6
  • React 不使用 ES6
var createReactClass = require('create-react-class')

// 调用该方法,创建一个有状态组件:
var Greeting = createReactClass({
  // 初始化 props
  getDefaultProps: function() {
    console.log('getDefaultProps')
    return {
      title: 'Basic counter!!!'
    }
  },

  // 初始化 state
  getInitialState: function() {
    console.log('getInitialState')
    return {
      count: 0
    }
  },

  render: function() {
    console.log('render')
    return (
      <div>
        <h1>{this.props.title}</h1>
        <div>{this.state.count}</div>
        <input type="button" value="+" onClick={this.handleIncrement} />
      </div>
    )
  },

  handleIncrement: function() {
    var newCount = this.state.count + 1
    this.setState({ count: newCount })
  },

  propTypes: {
    title: React.PropTypes.string
  }
})

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

state 和 setState

  • 注意:使用 setState() 方法修改状态,状态改变后,React 会重新渲染组件
  • 注意:不要直接修改 state 属性的值,这样不会重新渲染组件!!!
  • 使用:1 初始化 state 2 setState 修改 state
// 修改state(不推荐使用)
// https://react.docschina.org/docs/state-and-lifecycle.html#不要直接更新状态
this.state.test = '这样方式,不会重新渲染组件'
constructor(props) {
  super(props)

  // 正确姿势!!!
  // -------------- 初始化 state --------------
  this.state = {
    count: props.initCount
  }
}

componentWillMount() {
  // -------------- 修改 state 的值 --------------
  // 方式一:
  this.setState({
    count: this.state.count + 1
  })

  this.setState({
    count: this.state.count + 1
  }, function(){
    // 由于 setState() 是异步操作,所以,如果想立即获取修改后的state
    // 需要在回调函数中获取
    // https://react.docschina.org/docs/react-component.html#setstate
  })

  // 方式二:
  this.setState(function(prevState, props) {
    return {
      counter: prevState.counter + props.increment
    }
  })

  // 或者 - 注意: => 后面需要带有小括号,因为返回的是一个对象
  this.setState((prevState, props) => ({
    counter: prevState.counter + props.increment
  }))
}

组件绑定事件

  • 1 通过 React 事件机制 onClick 绑定
  • 2 JS 原生方式绑定(通过 ref 获取元素)
    • 注意:ref 是 React 提供的一个特殊属性
    • ref的使用说明:react ref

React 中的事件机制 - 推荐

  • 注意:事件名称采用驼峰命名法
  • 例如:onClick 用来绑定单击事件
<input
  type="button"
  value="触发单击事件"
  onClick={this.handleCountAdd}
  onMouseEnter={this.handleMouseEnter}
/>

JS 原生方式 - 知道即可

  • 说明:给元素添加 ref 属性,然后,获取元素绑定事件
// JSX
// 将当前DOM的引用赋值给 this.txtInput 属性
<input ref={ input => this.txtInput = input } type="button" value="我是豆豆" />

componentDidMount() {
  // 通过 this.txtInput 属性获取元素绑定事件
  this.txtInput.addEventListener(() => {
    this.setState({
      count:this.state.count + 1
    })
  })
}

事件绑定中的 this

  • 1 通过 bind 绑定
  • 2 通过 箭头函数 绑定

通过 bind 绑定

  • 原理:bind能够调用函数,改变函数内部 this 的指向,并返回一个新函数
  • 说明:bind第一个参数为返回函数中 this 的指向,后面的参数为传给返回函数的参数
// 自定义方法:
handleBtnClick(arg1, arg2) {
  this.setState({
    msg: '点击事件修改state的值' + arg1 + arg2
  })
}

render() {
  return (
    <div>
      <button onClick={
        // 无参数
        // this.handleBtnClick.bind(this)

        // 有参数
        this.handleBtnClick.bind(this, 'abc', [1, 2])
      }>事件中this的处理</button>
      <h1>{this.state.msg}</h1>
    </div>
  )
}
  • 在构造函数中使用bind
constructor() {
  super()

  this.handleBtnClick = this.handleBtnClick.bind(this)
}

// render() 方法中:
<button onClick={ this.handleBtnClick }>事件中this的处理</button>

通过箭头函数绑定

  • 原理:箭头函数中的 this 由所处的环境决定,自身不绑定 this
<input type="button" value="在构造函数中绑定this并传参" onClick={
  () => { this.handleBtnClick('参数1', '参数2') }
} />

handleBtnClick(arg1, arg2) {
  this.setState({
    msg: '在构造函数中绑定this并传参' + arg1 + arg2
  })
}