update:JSX语法

This commit is contained in:
qianguyihao 2019-02-12 16:54:26 +08:00
parent d4c89bb78e
commit 624aa4cad7

View File

@ -25,7 +25,7 @@ JSXJavaScript XML一种类似于XML的JS扩展语法。也可以理解成
运行 cnpm i babel-preset-react -D 运行 cnpm i babel-preset-react -D
``` ```
我们可以通过这个babel包将 JSX语法 转换为 JS语法。 这个babel包的作用是将 JSX语法 转换为 JS语法。
安装完成后就可以开始使用JSX语法了。 安装完成后就可以开始使用JSX语法了。
@ -233,7 +233,6 @@ React在解析所有标签的时候是以标签的首字母来区分的
**结论**:组件的首字母必须大写。 **结论**:组件的首字母必须大写。
### 父组件传值给子组件 ### 父组件传值给子组件
代码举例: 代码举例:
@ -288,20 +287,8 @@ React在解析所有标签的时候是以标签的首字母来区分的
``` ```
上方代码中我们是想把整个person对象传递给子组件所以采用了`...Obj 语法`语法。传递给子组件后,子组件获取的数据仅仅只是可读的。 上方代码中我们是想把整个person对象传递给子组件所以采用了`...Obj 语法`语法。传递给子组件后,子组件获取的数据仅仅只是可读的。
### 以文件夹的形式创建子组件
在实际开发中,我们通常会专门新建一个 components 文件夹,来定义子组件。
文件结构如下:
代码如下:
1components/hello.jsx:
## class 关键字的介绍 ## class 关键字的介绍
面向对象语言的三个特性:封装、继承、多态。多态 和 接口、虚拟方法有关。 面向对象语言的三个特性:封装、继承、多态。多态 和 接口、虚拟方法有关。
@ -310,7 +297,6 @@ React在解析所有标签的时候是以标签的首字母来区分的
myclass.js: myclass.js:
```javascript ```javascript
// 以前学习的:使用构造函数创建对象 // 以前学习的:使用构造函数创建对象
function Person(name, age) { function Person(name, age) {
@ -393,6 +379,9 @@ c1.say();
``` ```
注意上方 `constructor`处的注释:当使用 extends 关键字实现了继承, 子类的 constructor 构造函数中,必须显示调用 super() 方法,这个 super 表示父类中 constructor 的引用。也就是说,在子类当中,要么不写 constructor如果写了 constructor就一定要把 `super()`也加上。
为啥我们要引入 `class`这个功能?就是因为, `class`里,永远都存在着一个 constructor。我们可以利用 `constructor`做很多事情。
## 创建组件的第二种方式:使用 class 关键字 ## 创建组件的第二种方式:使用 class 关键字
@ -452,6 +441,92 @@ index.html:
``` ```
### 父组件传值给子组件
代码举例:
index.html:
```html
<!DOCTYPE html>
<html lang="">
<head>
<meta />
<meta />
<meta />
<title>Document</title>
</head>
<body>
<!-- 引入React相关的js库 -->
<script type="text/javascript" src="./libs/react.js"></script>
<script type="text/javascript" src="./libs/react-dom.js"></script>
<script type="text/javascript" src="./libs/babel.min.js"></script>
<div id="app"></div>
<!-- 注意,这一行的 type 是写 "text/babel",而不是 "text/javascript" -->
<script type="text/babel">
// 使用 class 创建的类,通过 extends 关键字,继承 `React.Component` 之后,这个类,就是一个组件的模板了。
// 如果想要引用这个组件,可以把类的名称以**标签的形式**,导入到 JSX 中使用。
class Hello2 extends React.Component {
constructor(props) {
super(props);
console.log(props.name);
// 注意:`this.state` 是固定写法,表示当前组件实例的私有数据对象,就好比 vue 中,组件实例身上的 data(){ return {} } 函数
// 如果想要使用 组件中 state 上的数据,直接通过 this.state.*** 来访问即可
this.state = {
msg: "这是 Hello2 组件的私有msg数据",
info: "永不止步"
};
}
// 在 class 实现的组件内部,必须定义一个 render 函数
render() {
// 在 render 函数中,还必须 return 一个东西如果没有什么需要被return 的,则需要 return null
return (
<div>
<h3>这是使用 class 类创建的组件 </h3>
</div>
);
}
}
ReactDOM.render(
<div>
<Hello2 name="qianguyihao"> </Hello2>
</div>,
document.getElementById("app")
);
</script>
</body>
</html>
```
## 方式一和方式二的对比
上面的内容里,我们使用了两种方式创建组件。这两种方式,有着本质的区别,我们来对比一下。
**对比**
- **方式一**:通过 function构造函数 创建组件。内部没有 state 私有数据,只有 一个 props 来接收外界传递过来的数据。
- **方式二**:通过 class 创建子组件。内部除了有 this.props 这个只读属性之外,还有一个专门用于 存放自己私有数据的 this.state 属性,这个 state 是可读可写的。
基于上面的区别,我们可以为这两种创建组件的方式下定义: 使用 function 创建的组件,叫做【无状态组件】;使用 class 创建的组件,叫做【有状态组件】。
**本质区别**
有状态组件和无状态组件,最本质的区别,就是有无 state 属性。同时, class 创建的组件有自己的生命周期函数但是function 创建的 组件,没有自己的生命周期函数。
**什么时候使用 有状态组件,什么时候使用无状态组件**
- 1如果一个组件需要存放自己的私有数据或者需要在组件的不同阶段执行不同的业务逻辑此时非常适合用 class 创建出来的有状态组件。
- 2如果一个组件只需要根据外界传递过来的 props渲染固定的页面结构即可的话此时非常适合使用 function 创建出来的无状态组件。(使用无状态组件的小小好处: 由于剔除了组件的生命周期,所以,运行速度会相对快一点点)。