React基础知识

161 阅读7分钟
  1. 本地环境搭建(来源于菜鸟教程):
  •   $ npm install -g cnpm --registry=https://registry.npm.taobao.org
      $ npm config set registry https://registry.npm.taobao.org
      $ cnpm install -g create-react-app
      $ create-react-app my-app
      $ cd my-app/
      $ npm start
    

2.为什么用JSX:

  • React.createElement是创建虚拟DOM自带函数。
  • 解决创建虚拟DOM复杂的问题。
  • xml:记录、保存数据。
  • Json代替,parase方法、stringfy方法。
  • 定义虚拟DOM时,不需要加上引号。
  • 标签中混入JS表达式时,需要使用{}。
  • 表达式总结:与js语句(代码)的区别,表达式会产生一个值,可以放在任何一个需要值的地方(就是可以拿一个变量去接住它的返回值)。而语句就是没有返回值。
  • 样式的类名指定用className指定。
  • 内联样式要用双大括号包含起来,并且要用驼峰形式。
  • 虚拟dom必须只有一个根标签。
  • 标签必须闭合。
  • 标签首字母:小写的话则将这个标签转为html中的同名元素,如果大写字母react就会去渲染对应的组件,没有就会报错。
  • 给React一个数组,它可以遍历。给它一个对象,它无法识别。
  • li必须要一个唯一的key。

3.虚拟DOM:

  • 本质是Object类型的一般对象。
  • 虚拟DOM比较轻量,真实DOM比较繁杂,因为虚拟DOM只是react内容使用,不需要真实DOM上面那么多的属性。
  • 虚拟DOM会被转换为真实DOM,呈现在页面上。

4.模块、组件、模块化、组件化:

  • 模块:js文件。复用js代码,提供js运行效率。
  • 组件:用来实现局部功能的代码和资源的集合(css、html、js、imag等),简化项目编码,提供项目运行效率。
  • 当应用的js以模块来编写,这个应用就是一个模块化应用。
  • 当应用是以多组件的模式来编写,这个应用就是一个组件化应用。

5.组件化开发;

  • 函数式组件:

  • 首字母大写,render里面写标签不是写函数,标签必须闭合。

  • 因为被bebel转换后开启了严格模式,所以函数组件中的this没有指向window。

  • 函数名就是组件名。

  • render执行了函数式组件标签发生了:

  • React解析函数式组件标签。

  • 找到该函数。

  • 调用它。

  • 将返回的虚拟DOM转为真实DOM,展示出来。

  • 类式组件:

  • 一般定义不需要构造函数。

  • 必须有render且包含return。

  • render执行了类式组件标签发生了:

  • 找到这个类。

  • 调用new去创建这个类的实例,调用实例的render方法。

  • Vdom转真实dom。

  • 显示。

  • 有状态的就是复杂组件(function暂时是简单组件,因为它调用时没有成一个类,也就没有实例):

  • 组件实例的state:

  • 在构造函数中初始化。

  • 原生事件的onclick里面是当成JS代码执行,而React里面是传入一个函数名就行了。

  • 类组件中定义的 数中的this如果没有指定的话,指向undefined,所以元素调用时,需要将该函数用bind函数绑定this的执行环境,不是通过实例调用的方法没法指向实例。

  • 状态不可直接更改,需要调用setState更改。这种更新是合并,不是替换。

  • 构造函数调用一次,而render函数调用1+n次,n是指状态改变的次数。

  • 需要初始化state状态,需要在构造函数中初始化。

  • 类中可以直接写赋值语句。相当于直接给实例定义一个属性和值。

  • 直接给类中的方法用箭头函数定义,就可以不用在构造函数中重定向this。

  • 组件也被称为状态机。

  • props学习:

  • render里面的return后面是()。

  • ...扩展运算符,展开一个数组,连接数组。不能展开对象。

  • {...对象}可以深拷贝一个对象,ES6语法。

  • react+babel可以让开发者使用...去扩展一个对象。但是仅用于标签属性的传递。

  • react元素里的{}是执行js语句的意思,和原生的{}含义不同,注意区别。

  • 使用PropTypes插件进行类型检测。

  • 使用defaultProps进行默认值设置。

  • 简写props可以把类的属性直接用static关键词修饰放到类内部。不然在类里面定义的是放在实例上面的。

  • 通常React中构造函数用于以下两种情况:

  • 通过给this.state赋值对象来初始化内部state。

  • 为事件处理函数绑定实例。

  • 构造器是否接收props,是否传递给super,取决于:是否希望在构造器中通过this访问props。

  • 函数式组件使用props:

  • 直接解析调用就行。

  • refs属性使用

  • 字符串使用模式已经要被弃用,因为其会引起一些效率问题。

  • 回调式使用refs。回调函数就是你定义的函数你没去调用。直接在ref属性中写回调函数拿到当前节点使用。内联调用回调函数会出现更新DOM时,调用两次的bug。第一次会输入null,是为了清空之前的函数定义。因为React为了效率问题,先清楚之前的函数定义。而把内联函数改为实例上定义的方法就不会出现这个问题,因为这样React就知道这个方法是之前已经使用过的方法。

  • 还可以使用createRef API的调用来创建refs:React.createRef()可以创建一个容器,可以容纳存储ref标识的节点。直接去里面取得节点就行了。该容器独立的,不能多个元素共存。

  • 事件处理:

  • 自定义事件,是为了更好的兼容性。

  • 使用事件委托。

  • 同样可以使用event.target拿到事件触发对象。

  • 不要过度使用ref。

  • 表单默认提交为get方式,表现为query。

  • 非受控组件:现用现取输入类组件。

  • preventDefault()是阻止默认事件。

  • 受控组件:改变过程中更新state,类似于Vue的双向绑定。可以帮助减少ref的使用。

  • 高阶函数和函数柯里化:

  • 接受函数作为传入参数或者返回值即为高阶函数。

  • Promise

  • settimeout

  • 数组的很多方法是高阶函数

  • 函数柯里化:函数作为返回值,最后统一处理所有传入参数。

  • React生命周期学习:

  • 挂载组件——mount,卸载组件——unmount。

  • 生命周期回调函数,生命周期钩子函数。

  • 挂载时:constructor、componentWillMount、render、componentDidMount、componentWillUnmount。

  • 更新时:

  • setState、shouldcompentUpdate、componentWillUpdate、render、compentDidUpdate。

  • forceUpdate,不经过shouldcomponentUpdate直接下面的钩子函数。

  • 父组件更新引起子组件的生命周期的触发:compeonentWillRecevieProps,第一次不算,后面才算触发。其他钩子是正常的。

  • 以上是旧的生命周期,总结如下:

  • 用的最多的生命周期函数:

  • render

  • componentDidMount-多用于一些初始化操作:例如开启定时器、定位等

  • componentWillUnmount-多用于停止定时器、释放内存等。

  • 新的生命周期对比:

  • componentWillMount、componentWillUpdate、compeonentWillRecevieProps前面必须加上UNSAFE前缀。表示后面版本中这三个函数可能会出现问题。

  • 新出现两个生命周期:

  • getDerivedStateFromProps:用于当state由props决定时的场合。

  • getSnapshotBeforeUpdate:用户记录更新之前的一些信息。

  • 以上是新的生命周期,总结如下:

  • 新增两个生命周期钩子。

  • render

  • componentDidMount-多用于一些初始化操作:例如开启定时器、定位、发起网络请求等等

  • componentWillUnmount-多用于停止定时器、释放内存等。

  • React Diff算法:

  • 最小维度是标签。

  • 逐层对比:

  • 对比的 旧数据的Vdom和新数据的Vdom。

  • Vdom上面标签的属性很少,例如input就没有value属性。

  • key的作用: