往期回顾:# React基础入门之虚拟Dom【一】
面向组件编程
react是面向组件编程
的一种模式,它包含两种组件类型:函数式组件及类式组件
函数式组件
注:react17开始,函数式组件成为主流
一个基本的函数组件长这个样子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>hello_react</title>
</head>
<body>
<!-- 准备好一个“容器” -->
<div id="test"></div>
<!-- 引入react核心库 -->
<script type="text/javascript" src="./js/react.development.js"></script>
<!-- 引入react-dom,用于支持react操作DOM -->
<script type="text/javascript" src="./js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script type="text/javascript" src="./js/babel.min.js"></script>
<script type="text/babel">
// 1、创建函数式组件
function Demo() {
return <h1>函数式组件</h1>;
}
// 2、渲染组件
ReactDOM.render(<Demo />, document.getElementById("test"));
</script>
</body>
</html>
页面效果如下:
函数名的注意事项
注意,渲染组件时,函数名称需要写成html
标签的形式。此外,函数名称不能使用小写的形式:
// 1、创建函数式组件
function demo() {
return <h1>函数式组件</h1>;
}
// 2、渲染组件
ReactDOM.render(<demo />, document.getElementById("test"));
如上,如果写成小写的形式,控制台会报错
这和Jsx的语法规则有关
遇到 <开头的代码, 以标签的语法解析: html同名标签转换为html同名元素, 其它标签需要特别解析
函数的执行者
上述代码中,我们并没有执行Demo函数,但当我们将它作为标签使用时,react帮我们执行了这个函数。
函数内的this指向
正常情况下,一个函数内的this应该指向window,但下面的示例中,this会是undefined
<script type="text/babel">
// 1、创建函数式组件
function Demo() {
console.log("this", this);
return <h1>函数式组件</h1>;
}
// 2、渲染组件
ReactDOM.render(<Demo />, document.getElementById("test"));
</script>
原因很简单,我们的代码是在babel环境下执行的,bable会开启严格模式,让我们this的指向不是window。
我们可以验证一下,打开bable官网,
复制上述代码进去
可以看到,我们函数式组件最终会被编译成一个普通函数(这印证了JSX是语法糖)。
类式组件
注:在最新的react18版本以后,这种写法已经不推荐了,但这是学习了解react重要的一环!
一个基本的类式组件长这个样子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>hello_react</title>
</head>
<body>
<!-- 准备好一个“容器” -->
<div id="test"></div>
<!-- 引入react核心库 -->
<script type="text/javascript" src="./js/react.development.js"></script>
<!-- 引入react-dom,用于支持react操作DOM -->
<script type="text/javascript" src="./js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script type="text/javascript" src="./js/babel.min.js"></script>
<script type="text/babel">
// 1、创建类组件
class MyComponent extends React.Component {
render() {
return <h1>这是一个类组件</h1>;
}
}
// 渲染组件
ReactDOM.render(<MyComponent />, document.getElementById("test"));
</script>
</body>
</html>
页面效果
类式组件的写法
类式组件必须继承React.Component这个父类,且函数内部必须调用render函数
class MyComponent extends React.Component {
render() {
return <h1>这是一个类组件</h1>;
}
}
我们知道,类的使用必须使用new关键词,但是上述代码我们并没有使用,那么MyComponent的实例是什么时候创建的?
在渲染组件时,react帮我们执行的。
ReactDOM.render(<MyComponent />, document.getElementById("test"));
执行代码后:
- react解析组件标签,找到了MyComponent组件
- 发现组件是使用类定义的,随后new出类的实例,并通过实例调用原型上的render方法
- 将render返回的虚拟Dom转换为真实Dom,随后呈现在页面中
render函数
render函数定义位置
根据类的知识,render函数是定义在MyComponent类 的原型上的,我们打开控制台验证下
render函数中的this指向
根据类的知识,我们知道render中的this应该是MyComponent的实例对象
我们打印下
// 1、创建类组件
class MyComponent extends React.Component {
render() {
console.log("render中的this", this);
return <h1>这是一个类组件</h1>;
}
}
可以看出,this确实是MyComponent的实例对象,同时也可以验证实例对象的prototype上的存在MyComponen的render方法
组件中的属性
观察打印出来的实例对象,我们可以发现实例对象上存在很多属性方法,如context、props等
这些方法我们没有在MyComponent类中定义,那它必然来源于继承的父类React.Component。这些组件上的属性方法,我们将在下一篇文章熟悉。