一. class 组件创建方式

import React from 'react';

class B extends React.Component {
  constructor(props){
    super(props);
  }
  render(){
    return (
      <div>hi</div>
    )
  }
}

二. Props 外部数据

class Parent extends React.Component {
  constructor(props){
    super(props)
    this.state = {name:'frank'}
  }
  onClick = ()=>{}
  render(){
    return <B name={this.state.name} onClick={this.onClick}>hi</B>
  } // 这里的name和onClick就是props,来源是从this.state来的,是从外部来的作为props
}

// props如何初始化,这样子做了之后this.props就是外部数据的对象地址了
class B extends React.Component {
  constructor(props){
    super(props);
  }
  render(){

  }
}

// 读取props
class B extends React.Component {
  constructor(props){
    super(props);
  }
  render(){
    return <div onClick={this.props.onClick}>
      {this.props.name}
      <div>
        {this.props.children}
      </div>
    </div>
  }
}

// 不能去写props,外部数据应该由外部更新

三. componentWillReceiveProps 的作用

  • 接收外部数据,只能读不能写,外部呀数据由父组件传递
  • 接受外部函数,在恰当的时机调用该函数,该函数一般是父组件的函数
import React from 'react';

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

  onClick = () => {
    this.setState({
      x: this.state.x + 1
    })
  }

  render(){
    return (
      <div className="App">
        App <button onClick={this.onClick}>+1</button>
        <B name={this.state.x}/>
      </div>
    );
  }
}

class B extends React.Component {
  UNSAFE_componentWillReceiveProps(newProps, nextContext) {
    console.log('旧的 props')
    console.log(this.props)
    console.log('props变化了')
    console.log('新的p props')
    console.log(newProps)
  }
  render(){
    return (
      <div>{this.props.name}</div>
    )
  }
}

export default App;

四. State & setState 内部数据

  • 初始化 State
class B extends React.Component{
  constructor(props){
    super(props);
    this.state = {
      user: {name:'frank', age:187}
    }
  }
  render(){

  }
}
  • setState 的两种方式,推荐写成函数的形式,一般就用第一个参数,还有第二个参数接受成功之后的回调函数,另外写 state 的时候会进行一级合并(shallow merge)
  onClick = () => {
    this.setState({
      x: this.state.x + 1
    })
    this.setState({
      x: this.state.x + 1
    })
  }

  onClick2 = () => {
    this.setState((state)=>({x:state.x+1}))
    this.setState((state)=>({x:state.x+1}))
  }

五. 生命周期

let div = document.createElement('div')
// 这是div的 create/construct 过程
div.textContent = 'hi'
// 这是初始化state
document.body.appendChild(div)
// 这是div的mount过程
div.textContent = 'hi2'
// 这是div的update过程
div.remove()
// 这是div的unmount过程
  • 函数列表,以下是常用的
constructor() - 这里初始化state
shouldComponentUpdate() - return false 阻止更新
render() - 创建虚拟DOM
componentDidMount() - 组件已出现在页面
componentDidUpdate() - 组件已更新
componentWillUnmount() - 组件将死
  • constructor的用途

    • 初始化props
    • 初始化state,但此时不能调用setState
    • 用来写bind this

        constructor(){
            this.onClick = this.onClick.bind(this)
        }
        可以用新语法代替
        onClick = ()=> {}
        constructor() {
      
        }
    • 可不屑
  • shouldComponentUpdate的用途

    • 返回true表示不阻止UI更新
    • 返回false表示阻止UI更新
    • 示例见下页
    • 面试常问: shouldComponentUpdate有什么用?
    • 答: 它允许我们手动判断是否要进行组件更新,我们可以根据应用场景灵活地设置返回值,以避免不必要的更新
  • React.PureComponent会对state和props进行浅对比,就不需要shouldComponentUpdate了
  • render的用途

    • 展示视图,
    // return 对应的对象是不是一个dom元素, 而是一个表示dom元素的对象, 我们称其虚拟dom 
    return (<div>...</div>)
    • 只能有一个根元素
    用React.Fragment做占位,也可以写成<></>,两者等价
    • 技巧

      // render里面可以写if...else
      // 可以写?:
      // 不能直接写for,需要用数组
      // 可以写array.map 
      
      import React from 'react';
      
      class App extends React.PureComponent {
        constructor(props){
          super(props)
          this.state = {
            n:1
          }
        }
        onClick= ()=>{
          this.setState(state=> ({
            n: state.n+1
          }))
        }
        
        render(){
          console.log('render了一次')
          let message
          if(this.state.n % 2 === 0 ) {
            message = <div>偶数</div>
          } else {
            message = <span>奇数</span>
          }
          return (
            <>
              {message}
              <button onClick={ this.onClick }>+1</button>
            </>
          )
        }
      }
      
      export default App;
      // 循环的写法
      render() {
        return this.state.array.map(n=><span key={n}>{n}</span>)
      }
    • componentDidMount()的用途

      • 在元素插入页面后执行代码,这些代码依赖DOM
      • 比如你想获取div的高度,就最好在这里写
      • 此处可以发起加载数据的AJAX请求(官方推荐)
      • 首次渲染会执行此钩子

        componentDidMount() {
        const div = document.getElementById('xxx')
        const {width} = div.getBoundingClientRect()
        // console.log(width)
        this.setState({width})
        }
        
        render(){
          return(
            <div id='xxx'>Hello World, {this.state.width}
            </div>
          )
        }
      • 也可以用ref来做

        import React from 'react';
        
        class App extends React.PureComponent {
          constructor(props){
            super(props)
            this.state = {
              n:1,
              width: undefined
            }
            this.divRef = React.createRef()
          }
          onClick= ()=>{
            this.setState(state=> ({
              n: state.n+1
            }))
          }
        
          componentDidMount() {
            const div = this.divRef.current
            const {width} = div.getBoundingClientRect()
            // console.log(width)
            this.setState({width})
          }
        
          render(){
            return(
              <div ref={this.divRef}>Hello World, {this.state.width}px
              </div>
            )
          }
        }
        
        export default App;
        
    • componentDidUpdate()的作用

      • 在视图更新后执行代码
      • 此处也可以发起AJAX请求,用于更新数据(看文档)
      • 首次渲染不会执行此钩子
      • 在此处setState可能会引起无限循环,除非放在if里
      • 若componentDidUpdate返回false,则不触发此钩子
      • componentWillUnmount的用途

        • 组件将要被移除页面然后被销毁时执行的代码
        • unmount过的组件不会再次mount
        • 举例:
        如果你在componentDidMount里面监听了window scroll
        那么就要在componentWillUnmount的用途里面取消监听
        如果你在componentDidMount里面创建了Timer
        那么就要在componentWillUnmount里面取消Timer
        如果你在componentDidMount里面创建了AJAX请求,这种情况比较特殊,数据还没回来你就死了 
        那么就要在componentWillUnmount里面取消请求
    • 总结:

      • 能用函数组件就用函数组件,能用purecomponent就用purecomponent,最后不行采用 react.component
      • 生命周期函数
        生命周期.png

最后,个人微信,欢迎交流,提供工作机会。

wechat0.jpg


codingories
9 声望2 粉丝

不想当制作人的rapper不是好程序员!