react初探

React 基础


介绍

vue 数据双向绑定   虚拟 dom(js 对象模拟)  两大核心   组件化   数据驱动

react (facebook 出品)

  • 用于构建用户界面的 js 库,相当于 mvc 中的 v, mvvm
  • 采用组件化模式声明式编码,提高开发效率及组件复用率。
  • 声明式编码没有 if for switch。用一个变量接收函数或变量。
  • https://blog.csdn.net/weixin_30700099/article/details/97463669
    • 组件化 jsx 组件包含了标签样式和交互,柔和在一起,就出现了 jsx
  • React Native 中可以使用 React 语法进行移动端开发
    • 一次学习,随处编写 learn once everywhere 可以写 app,可以写桌面端的程序
  • 虚拟 dom(dom 树的 js 对象,diff 算法),减少与真实 DOM 的交互
  • 单向数据流(数据只能单向传递,原理数据(函数)的作用域。内层数据可以访问外层,外层获取不到内层,但通过闭包可以把数据传递到函数外。vue 有状态管理,react 也是状态管理)
  • 且 react 的状态更新是异步的,并不是说 setState 这个方法是异步的,而是引起的后续 react 自己搞的操作是异步的。

全家桶 路由 redux|mobx  请求 axios  ui 框架  antd material ui s

引入


CDN 链接   引入使用

1
2
3
4
5
6
7
8
9
10
11
12
13
<script
crossorigin
src="https://unpkg.com/react@16/umd/react.development.js"
></script>
<script
crossorigin
src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"
></script>
<script
crossorigin
src="https://unpkg.com/babel-standalone@6/babel.min.js"
></script>
<script type="text/babel"></script>


关于虚拟 DOM

  • 本质是 Object 类型的对象(一般对象)
  • 虚拟 DOM  比较‘轻’,真实 DOM 比较‘重’,因为虚拟 DOM 是 React 内部作用,无需真实 DOM 上那么多的属性。
  • 虚拟 DOM 最终会被 React 转化为真实 DOM,呈现在页面上.

JSX

  • js 创建多级元素会很痛苦

  • jax 语法才是人能写的

  • jax 的虚拟 dom 写法其实就是原始虚拟 dom 写法的语法糖

js 表达式

一个表达式会产生一个值,可以放在任何一个需要值的地方。就是可用 变量接收的都是 js 表达式。

1
2
3
4
5
a;
a + b;
demo(1);
arr.map();
function test() {}

js 语句 (代码块)

1
2
3
if(){}
for(){}
switch(){case:xxxx}

知识点

  • 定义虚拟 DOM 时,不能用   引号
  • 插值绑定 {js 代码}
  • { }中 可以只能写 js 表达式,不能用 js 语句。使用的都是基础的三元运算。
  • 样式 class 改为 className
  • 事件绑定使用小驼峰写法,onclick 改写成 onClick –on 后面的首字母大写 。值使用 {js 表达式}
    • 因为 react 为了更好的兼容型,把这这些事件都重新封装一遍。
  • 内联样式 style 必须用对象,对象原来是连字符,现在是小驼峰
    • 要用双花括号写,第一层花括号是 js 语法的花括号,第二层花括号是对象。
  • 标签必须要关闭  
  • 注释:
    • {/* **  用{ }包住   注释// –相当于 js 表达式中就是注释  ***/}**
    • 脚手架中快捷键 ctrl + /
  • 标签首字母
    • 若小写字母开头,则将该标签转为 html 中的同名元素。
    • 若如果是大写字母开头,react 就去渲染对应的组件。
  • 只能有一对根标签
    • 多默认使用
      ,但此节点很多余。
    • 可直接空标签 <></> ,但不能写任何属性
    • 或使用  需要在 react 中先引入此组件,这个组件只能有 key 这一个属性。不会渲染节点,但也不违反 jsx 语法规则。很巴适。

类式组件

类中直接写赋值语句

列如: a =1;

**    –就相当于给这个类的实例对象中添加了一个属性。**

**    如果在   赋值语句前加上** static**  关键字**

** **   列如   static a =1;

**    –就相当于在这对这个类本身添加了一个属性**

  • 概念,允许将 ui 拆分成独立的可以单独使用的片段
  • 组件 写法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class 组件名 extends React.Component{ //Component是个函数
constructor(){ // 构造函数 --可以不写
// construtor可以传递 props。是否传递取决于,是否要在 构造器中使用this.props
super() // 继承父亲所有的属性方法
this.state={ // 数据
num=0,
// 属性
}
}
render(){ //必须调用该方,返回的是ui,只有一个根节点
return(
// 组件体
)
}
}

使用 <组件名/> 得大写

函数式组件

–简单组件,组件首字母必须大写,才是组件。

–展示形组件,ui 组件,不管逻辑,只管显示和调用

–函数式组件,没有 state,没有生命周期,只用于 ui 展示

–数据和数据的逻辑处理,放在父组件中,其它的子组件需要有逻辑处理的时候,调用父组件的方法。

但现在 随着官方 hooks 的加入。 函数式组件成为的主流,性能更好,代码组织更简约。

事件绑定

  • onClick={this.funName}
  • funName(){}  写到   组件内

–组件的方法都写到组件实例对象内

**–构造器中的 this 指向组件实例对象,render 中的 this 也指向组件实例对象,****但是类的方法用 onClick 绑定使用时,this 为 undefined**

  • 因为类的方法是作为 onCllick 的回调,所有不是通过实例调用的,是直接调用。只有通过实例调用类的方法时,类的方法中的 this 才指向组件实例对象。<那个调用 this 就指向谁>
  • 类的方法默认开启了局部的严格模式,所有自定义事件中的 this 为 undefinde.

推荐解决方法:

改变 funName 中的 this 指向

  • 在构造函数中 声明一个属性事件   将其 this 指向绑定为构造函数的 this 指向 > this.funName=this.funName.bind(this)
    • bind(this 指向,属性)  可以生成一个新函数。调用时才执行
  • 在 render 组件体事件中绑定 > { this.funName.bind(this) }
  • 在 render 组件体事件中使用箭头函数 > { ()=>this.funName() }
  • 或者把 funName 写成箭头函数。

函数传参调用

  • 这种写法表示 自己已调用了这个函数。然后在事件触发后,react 就只是帮你回调这个函数的返回值而已。

  • 所有该事件的返回值必须是一个函数。
    • 并且只有 react 帮你回调时,函数中才拿得到 event 事件对象
    • 白色框中就是 react 帮你回调的函数

**    **

状态管理

  • 在 constructor 中 this.state={ } 存放的状态(数据)
  • 获取 this.state.keyName
  • 设置 this.setState({keyName:value})
    • setState 是个异步的,同一个函数内。多个 setState 不会一个一个挨着执行,是最后合并在一起之后再执行。最后的会覆盖前面的,就只会执行最后一个。
    • setState 的第二参数是回调函数,回调函数内部可以拿到修改后的 state

组件传值

1.父传子

  • 父组件-传

<com attr1={state}/>

  • 子组件-取

<div> {this.props.attr1} </div>

  • 父组件传输属性给子组件
    • 通过属性绑定给子组件,子组件通过 this.props 就可以拿到父组件通过属性传递的值
    • props 和 sate 的区别
      • state 是组件内部的值,在组件内部可以修改
      • props 是父组件传递来的值,只读,不可以改,如果需要改,需要调用父组件的方法实现。

2. 子传父

子传父   其实本质还是   父传子

  • **子传父。子****调用父组件的方法实现。**
    • 父传: propsFun**={this.fatherfun.bind(this)}**
    • 子接:**this.props.****propsFun**
  • 子组件通过,this.props.callback(参数)调用父组件的方法,可以传参,可以修改父组件的 state
  • 父组件定义自定义函数,属性名 callback
    • callback 为自定义名

扩展

React.StrictMode

index.js 入口文件中 **<React.StrictMode/>**包裹根 dom

  • 可对你所有组件的语法进行合理性的检查。比如禁止你使用一些官方已经不推荐的写法:如字符串 ref


import 问题

  • 该种导入   并不是结构赋值,而是 react 库中,本身就有 Component 的单独导出。之所以 react 中也有 Component 这个属性,是因为 Component 单独导出后被添加到了 react 的属性中。所以不要误会这是结构赋值了。
  • react 脚手架中 jsx、js 的文件都不用使用后缀了,因为 react 帮你配置了 webpack。
  • 引用 js、jsx,使用 index 命名,就只有引用其外层的文件夹即可,webpack 配置了的。

执行 ReactDOM.reander(…)后发生了什么

  • React 解析组件标签,找到了 MyComponet 组件
  • 发现组件是使用类定义的,随后 new 出来该类的实例,并通过该实例调用到原型上的 render 方法。
  • 将 render 返回的虚拟 DOM 转为真实 DOM,随后呈现在页面上

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!