两组组件定义

  • 类组件(class组件)

特点:用ES6面向对象语法,有生命周期,有this,有state,有上下文,有ref,永远不能使用Hooks.

缺点:相对函数组件,类组件性能相对较差。

class A extends Component {
  constructor (props) {
    super(props)
    // 定义声明式变量
    this.state = {
      num: 1
    }
  }
  componentDidMount () {
    console.log('---页面渲染完成')
    this.refs.box.style.color = 'red'
  }
  componentDidUpdate () {
    console.log('---页面更新完成')
  }
  add () {
    this.setState((state)=>({num: state.num+1}))
  }
  // 成员方法
  render () {
    console.log('---render/rerender')
    console.log('---props', this.props)
    const { num } = this.state
    // 返回视图模板(JSX)
    return (
      <h1 ref='box'>类组件 {num} <span onClick={()=>this.add()}>自增</span></h1>
    )
  }
}

export default A
  •  函数组件(自React诞生之初就有的写法)

特点:用函数编程,没有生命周期,没有state,没有this,没有上下文,没有ref,自React(16.8)版本之后可以使用Hooks,可以使用Hooks API在函数组件模拟没有生命周期,没有state,没有this,没有上下文,没有ref缺失的特性。

优点:相对于类组件,性能更好。

注意:无论是类组件还是函数组件,都有props(父子通信的纽带),在类组件中使用this.props访问,在函数组件中它的入参就是props。

注意:在React(16.8)之前是没有Hooks的,在React(16.8)之后才新增的Hooks。

function B (props) {
  console.log('---props', props)
  // 模拟state声明变量
  const [num, setNum] = useState(1)
  // 使用ref
  const box = useRef(null)
  // 模拟生命周期
  useEffect(()=>{
    console.log('---页面渲染/更新完成')
    if (num === 1) {
      box.current.style.color = 'blue'
    }
  }, [num])

  return (
    <h1 ref={box}>函数式组件 {num} <span onClick={()=>setNum(num+10)}>自增</span></h1>
  )
}

export default B

 理解jsx语法

  1. JSX(JavaScript XML)语法,由Facebook发布的,浏览器是不支持这种语法。
  2. 在编写React组件视图结构时,JSX是可选的,可以使用React.createElement('tag',{},[]编写视图结构)官方推荐使用JSX。
  3. JSX语法最终会被@babel/preset-react进行编译,编译的结果就是React.createElement()语法。
  4. JSX元素:本质上就是React.createElement()的返回值,是变量,也是对象,并且是不可变的对象。
  5. 为什么JSX元素是不可变对象?因为JSX元素最终会被渲染成真实DOM,所以不能直接操作“原材料”,而是只能使用声明式变量。
  6. 什么是元素?由JSX语法或React.createElement()返回的结果叫做元素,元素就是组件实例化的对象。
  7. 什么是组件?由class或function定义的东西叫做组件。

深入理解JSX语法细节

  1. 在JSX可以嵌套表达式,使用{}来嵌套,在JSX视图中凡是动态的变量(表达式)都使用{}包裹起来。

  2. JSX是变量,也是表达式,所以JSX元素可以作为函数的入参,也可以作为函数的返回值,还可以用在if或for循环中。

  3. JSX语法三个变化属性:className(class),tabIndex(tabindex),htmlFor(for)
  4. JSX语法新增的三个属性:key(用于列表渲染),ref(快捷的Dom方式),dangerouslySetInnerHTML(用于渲染HTML片段)

  5. 内联style语法: <div style={{ cssKey1: 'cssValue1', cssKey2: 'cssValue2' }} /> 
  6. className语法: <div className='box' className={`${cc} ff`} /> 
  7. 在JSX中,使用{}渲染后端接口数据,默认支持反注入攻击(XSS)

  8. JSX是对象,因为JSX变量是React.createElement()的返回值,这个返回值就是对象结构,所以JSX是对象。这中JSX对象就是"Fiber单元",很多嵌套“Fiber单元”就构成了“Fiber树”(双向链表)。

  9. JSX支持点语法: React.Componenet、<React.Fragment />、<Qf.Button /> 
  10. 在JSX中,向子组件传递props时,支持属性展开语法 <Child {...cPorps} /> 

  11. 在使用自定义组件时,哪些被自定义组件所嵌套的内容,在子组件中使用props.children来接收。props.children可以说基本数据类型,引用数据类型,函数。

  12. 在JSX中默认可以支持对数组直接渲染 <div>{ [<div />, true, null, 100, {a:1,b:2}, [1,2,3]] }</div> 

  13. 在JSX中,使用{}渲染Boolean,null,undefined都会被忽略。以下显示的结果相同。

    <div />
    
    <div></div>
    
    <div>{false}</div>
    
    <div>{null}</div>
    
    <div>{undefined}</div>
    
    <div>{true}</div>
08-11 19:52