01-3 React组件(类组件、函数组件、props、state)

目录

  • 类组件和函数组件
  • 如何使用 props 和 state
    外部数据和内部数据
  • 如何绑定事件
  • 复习this

1.组件 component

1.1 Element 和 component

  • const div = React.createElement('div',...)
    这是一个React元素(d小写)
  • const Div = ()=> React.createElement('div',...)
    这是一个React组件(D大写)

1.2 什么是组件

  • 能跟其他物件组合起来的物件,就是组件
  • 在React中,一个返回React元素的函数就是组件
  • 在Vue中,一个构造选项就可以表示一个组件

1.3 React两种组件

  • 一、函数组件
    使用方法:
    1.组件当标签用
    2.name="frank"会自动变成props的keyvalue
function Welcome(props){
     
//相当于 return 一个 React.creareElement
  return <h1>Hello, {
     props.name}</h1>
}
  • 二、类组件
    使用方法:
class Welcome extends React.Component{
     
  render(){
     
  //渲染组件视图
    return <h1>Hello, {
     this.props.name}</h1>
  }
}

1.4

  • React中的这种标签不是在写HTML
  • babel就把这个语法翻译为JS语法
  • 会被翻译为:React.createElement('div')
    如果是原生的标签,则会变成字符串
  • 会被翻译为:React.createElement(Welcome)
    如果是自定义的组件,后面就是函数

1.5 React.createElement的逻辑

  • 如果传入一个字符串 ‘div’,则会创建一个 div(虚拟DOM元素)
  • 如果传入一个函数,则会调用该函数,获取其返回值
    返回值获取到的标签会代替原来标签的位置,就不存在了
  • 如果传入一个类,则在类前面加个 new(这会导致执行 constructor对应函数),获取一个组件对象,然后调用对象的 render 方法,获取其返回值
    1.constructor就是new对应的函数
    2.要初始化state就要在constructor(构造函数)里面初始化
class Welcome extends React.Component{
     
  constructor(){
     
    super()
    this.state={
     n:0}
  }
  render(){
     
    return <h1>Hello, {
     this.props.name}</h1>
  }
}

2.案例

  • 代码
  • 一个小tip:析构函数
    const [n, setN] = React.useState(0);
    声明一个变量为0,然后对它进行读(n)和写(setN)
    setN之后就会得到一个新的n,而不是改变原有的n

2.1 添加props(外部数据)

  • 传递:messageFor+组件名=‘字符串’/{变量}
  • 类组件直接读取属性:this.props.xxx
    {this.props.messageForSon}
  • 函数组件直接读取参数:props.xxx
    箭头函数的括号里添加参数props
    {props.messageForGrandson}
  • 外部数据只能读,不能写

2.2 添加state(内部数据)

  • state也就是Vue的data
  • 类组件:this.state 读,this.setState 写
    1.使用setState的时候对象要重写一遍:React的思想,数据不可变,要变就产生新的对象
    2.React没有监听n,因此不能直接修改n
    3.因此使用setState告诉React更新了
add() {
     
  // this.state.n += 1 为什么不行
  this.setState({
      n: this.state.n + 1 });
}
  • 类组件:setState的更优写法
    问题:setState是一个异步更新UI的过程,它会等整个add函数代码运行完才更新n(如:),如果add中有其他对n的操作,就没办法对最新的n值操作
    解决:使用函数接受旧state,然后对旧state进行更新,这样就可以在函数内部获取新的n,并且对最新值进行操作
add(){
     
  this.setState((state)=>{
     
  //接收旧的state,返回新的state
    const n = state.n+1 //获取新的n
    console.log(n)//操作最新的n
    return {
     n}
  })
}
  • 函数组件:React.useState 返回数组,第一项读,第二项写
    用的时候给一个初始值就行
    const [n, setN] = React.useState(0);
    1.setN永远不会改变n,会产生一个新的n

2.3 类组件注意事项

  • this.state.n += 1 无效
    1.其实n已经改变,只不过UI不会自动更新而已
    2.调用setState才会触发UI更新(异步更新)
    3.因为React没有像Vue监听data一样监听state
  • setState会异步更新UI
    1.setState之后,state不会马上改变,立马读state会失败
    2.更推荐:setState(函数)
  • this.setState(this.state) 不推荐
    1.React希望我们不要修改旧state(不可变数据)
    2.常用代码:setState({n:state.n+1})

2.4 函数组件

  • 跟类组件不同的地方:没有this
    一律使用参数和变量

3.两种编程模型
01-3 React组件(类组件、函数组件、props、state)_第1张图片

  • Vue的编程模型:对数据的修改,会直接映射到UI上面
    1.一个对象对应一个虚拟DOM
    2.当对象属性改变时,把属性相关的DOM节点全部更新
    3.如当n发生变化,则Vue把n出现的地方全部重新渲染
  • React的编程模型:不能修改之前的数据,直接新建一个数据对象
    1.一个对象对应一个虚拟DOM
    2.另一个对象,对应另一个虚拟DOM
    3.对比两个虚拟DOM,找不同(DOM diff),然后局部更新DOM

4.复杂 state

  • 类组件里有n和m
    set的时候可以只set一部分,因为它会自动沿用以前的属性
  • 函数组件里有n和m
    不会自动合并以前的属性
    ...this.state把之前的数据拷贝过来
  • 总结
    1.类组件的setState会自动合并第一层属性
    2.但不会合并第二层属性,需要使用Object.assign或者...操作符
    3.函数组件的setX则完全不会合并
    4.要合并只能用...操作符

5.事件绑定

  • 两个步骤
    1.事件名=箭头函数
    2.使用:this.函数事件名
//事件名赋值
addN = ()=> this.setState({
     n: this.state.n + 1})
//绑定事件
<button onClick={
     ()=> this.addN()}>n+1</button>

6.React 和Vue

  • 相同点
    1.都是对视图的封装,React是用类和函数表示一个组件,而Vue是通过构造选项构造一个组件
    2.都提供了createElement的XML缩写,React提供的是JSX语法,而Vue提供的是模板写法
  • 不同点
    React是把HTML放在JS里面写,而Vue是把JS放在HTML里面写(三个标签)

你可能感兴趣的:(前端框架)