2022/6/16

定义React组件或者书写React相关代码为什么要导入React

  • 前情: 我们在开发项目的时候,创建每一组件,组件的第一行都会引入React,然而发现并没有使用过它, 不引入React的时候会报React没有定义的错误
import React from 'react';
  • React的运行机制能够解释一切,react的运行大概分成了三个阶段:

    1. jsx(也就是javascript xml)对象转变成javascript对象
    2. javascript对象转变成虚拟DOM对象
    3. 虚拟DOM对象变成实际的DOM对象
  • 在第一阶段其实主要用到了Babel。Babel主要的功能就是转码功能,将ES6转换成ES5。组件经过Babel转码之后可以看到React.createElement(....), 所以说明React是在转码之后使用的,我们在写代码的时候从表面上是看不出来React被使用了。

  • 我们在React项目使用Babel的时候,主要用到了这三个:

    • babel-core

    • babel-preset-env

    • babel-plugin-transform-react-jsx

//并且通常都会创建一个.babelrc的文件,文件中内容基本都如下:
{    
  "presets": ["env"],    
  "plugins": [        
    ["transform-react-jsx", 
     {            
       "prama": "React.createElement"        
     }
    ]    
  ]
}
  • 可以看到在使用babel-plugin-transform-react-jsx插件的时候,会需要调用React.createElement,这也就解释了为什么每个React组件页面都需要引入React的原因。

vue中keep-alive的作用

  • 理解: keep-alive 是 Vue 的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 transition 相似,keep-alive 是一个抽象组件:它自身不会渲染成一个 DOM 元素,也不会出现在父组件链中。

  • 作用: 可以实现组件缓存,当组件切换时,主要用于保留组件状态或避免重新渲染

  • 属性:

    • include:字符串或正则表达式。只有匹配的组件会被缓存。
    • exclude:字符串或正则表达式。任何匹配的组件都不会被缓存。
  • 举例子: 有一个列表页面和一个详情页面,那么用户就会经常执行打开详情->返回列表->打开详情,这样的话列表和详情都是一个频率很高的页面,那么就可以对列表组件使用进行缓存,这样用户每次返回列表的时候,都能从缓存中快速渲染,而不是重新渲染。

调用setState之后发生了什么

  • 首先setState的出现是因为,React并不会绑定视图和state,需要手动去更新视图,所以setState就出现了,它帮助我们更改数据的同时并且通知视图进行渲染。
  • 第二个能力是性能优化,可以认为setState是异步的,React在setState之后,会经对state进行diff,判断是否有改变,然后去diff dom决定是否要更新UI。如果这一系列过程立刻发生在每一个setState之后,就可能会有性能问题。在短时间内频繁setState。React会将state的改变压入栈中,在合适的时机,批量更新state和视图,达到提高性能的效果。(简单理解为批量处理,或者延迟处理)
  • 在代码中调用setState函数之后,React 会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程(Reconciliation)。经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个UI界面。在 React 得到元素树之后,React 会自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化重渲染。在差异计算算法中,React 能够相对精确地知道哪些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲染。

react的受控组件和非受控组件

非受控组件

  • 定义: 页面中所有输入类DOM的值,都是现用现取
  • 表单数据由DOM本身处理。即不受setState()的控制,与传统的HTML表单输入相似,input输入值即显示最新值(使用时通过ref从DOM获取表单值)
// 一个非受控组件的案例(表单元素中的值是当点击了按钮的时候才取到的)
// 创建组件
class Login extends React.Component {
  handleSubmit = (event) => {
    event.preventDefault() // 阻止表单提交
    const {username, password} = this
    alert(`您输入的用户名是 ${username.value},您输入的密码是:${password.value}`)
  }
  render() {
    return (
      <form action="https://www.baidu.com/" onSubmit={this.handleSubmit}>
        用户名:<input ref={c => this.username = c} type="text" name="username" />
        密码:<input ref={c => this.password = c} type="password" name="password" />
        <button>登录</button>  
      </form>
    )
  }
}
// 渲染组件
ReactDOM.render(<Login />, document.getElementById('test'))

//原生知识点回顾:
form中的action是表单的提交地址
name是接收数据的字段名(来收集存储对应的数据)

受控组件

  • 页面中输入类的DOM,随着输入的过程,通过 setState() 更新state中的数据,需要用的时候在从状态state中取(有点类似Vue中的双向数据绑定),而呈现表单的React组件也控制着在后续用户输入时该表单中发生的情况,以这种由React控制的输入表单元素而改变其值的方式,称为:“受控组件”。
  • 标签 input、textarea、select的值的改变通常是根据用户输入进行更新,所以受控组件是必须要有value的,value用来传入一个参数,结合onchang来控制这个参数输出。

  • 每当value变化的时候,都会调用onchange的方法,事件处理器拿到新的值之后就会重新渲染视图,更新表单

  • 备注:其中,文本框、下拉框都用的是event.target.value,而多选框用的是event.target.checked。 value和onchange两者在受控组件中缺一不可,一旦缺少其中一个就会报错

// 受控组件的案例
// 创建组件
class Login extends React.Component {
  // 初始化状态
  state = {
    username: '',
    password: ''
  }
  // 保存用户名到状态中
  saveUsername = (event) => {
    this.setState({username: event.target.value})
  }
  // 保存密码到状态中
  savePassword = (event) => {
    this.setState({password: event.target.value})
  }
  // 表单提交的回调
  handleSubmit = (event) => {
    event.preventDefault()
    //一个数据怎么获取主要取决于这个数据存储的形态
    const {username, password} = this.state
    alert(`您输入的用户名是 ${username},您输入的密码是:${password}`)
  }

  render() {
    return (
      <form action="https://www.baidu.com/" onSubmit={this.handleSubmit}>
        用户名:<input onChange={this.saveUsername} type="text" name="username" />
        密码:<input onChange={this.savePassword} type="password" name="password" />
        <button>登录</button>  
      </form>
    )
  }
}
// 渲染组件
ReactDOM.render(<Login />, document.getElementById('test'))

//注意
 <input onChange={this.saveUsername} type="text" name="username" />
 //这里是将saveUsername给onChange作为回调函数
 <input onChange={this.saveUsername('username')} type="text" name="username" />
 //而这里是将'username'作为一个参数传递给saveUsername()函数之后将函数执行结果作为回调函数给onChange,而这个函数如果没有返回值,传入的就是一个undefined
posted @ 2022-06-16 08:02  嘻嘻不是菜鸟了  阅读(27)  评论(0)    收藏  举报