持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情
最近打算学习一下react,之前一直都是在使用vue,一直都听说react挺火的,想了解一下和vue有什么不一样,刚好在github上看到了一个30-Days-Of-React的项目,因此想开一个专栏来记录一下学习react的过程
本专栏不会严格按照30 days去写30篇文章,大致看了一下其实发现很多东西都比较基础,所以一天内都能学挺多的了其实,不过今天是第一天,就还是简单记录一下,对react有个大概认知先,后续的文章我会将多天的内容整合到一篇文章来发布
由于只是简单使用,所以不会通过脚手架的方式去创建,而是用CDN的方式,方便我们快速上手
1. 认识JSX
首先介绍一下JSX,全名是JavaScript XML,它允许我们直接在js中编写html的代码
在vanilla(也就是原生js)中,我们都是通过createElement这一API创建DOM元素去动态操作html的
而在react中,并不需要显示调用类似createElement这样的API,而是通过JSX直接表示要用到的DOM元素
但是JSX并不是纯js代码,它是怎么被浏览器解析执行的呢?可以通过babel帮助我们完成这一需求,这个待会搭建环境的时候会讲到
首先大概了解一下JSX长啥样吧,既然说了是直接在js中编写html,那么很理应长成下面这样
const jsxElement = <p>Hello JSX</p>
可以看到,并不需要加上任何引号表明它是一个字符串,直接使用html的标签即可
2. 搭建环境
2.1 通过babel转换jsx代码
由于要使用babel帮我们将jsx代码转成js代码,所以我们的cdn中需要引入babel
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Getting Started React</title>
</head>
<body>
<div id="app"></div>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
// 这个 script 标签中的代码会被 babel 处理
</script>
</body>
</html>
2.2 引入react和react-dom
react和react-dom应当放在babel的上面,这样才能被babel处理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Getting Started React</title>
</head>
<body>
<div id="app"></div>
<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 src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
// 这个 script 标签中的代码会被 babel 处理
</script>
</body>
</html>
body中有一个id为app的div标签,作为整个react项目的挂载容器,所以我们需要获取到这个DOM元素,这是整个项目中唯一一处要使用原生操作DOM的地方
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Getting Started React</title>
</head>
<body>
<div id="app"></div>
<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 src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
// 获取根元素作为 react 挂载的容器
const app = document.querySelector('#app');
// 创建一个 JSX 元素
const jsxElement = <h1>Hello JSX</h1>;
ReactDOM.render(jsxElement, app);
</script>
</body>
</html>
运行后就能够将jsx元素渲染出来了
3. 使用JSX
前面我们简单地创建了一个jsx元素,并通过ReactDOM的render函数将jsx挂载到了根容器元素中,接下来我们看一下jsx的更多用法
3.1 组合多个JSX
假设我们的网页会有header、main和footer三部分,如果全都写成一个jsx会不太好管理
所以我们可以单独写成三个jsx
// 获取根元素作为 react 挂载的容器
const app = document.querySelector('#app');
// 创建三个 jsx 元素
const header = (
<header>
<h1>Hello JSX</h1>
</header>
);
const main = (
<main>
<p>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Facilis
animi, tempora tenetur eos commodi, veritatis atque qui obcaecati
reiciendis fugit nemo repellat architecto, impedit dolor aliquam
saepe illum ut nobis?
</p>
</main>
);
const footer = (
<footer>
<p>Copyright 2022</p>
</footer>
);
// 将三个 jsx 元素组合起来
const appJsx = (
<div>
{header}
{main}
{footer}
</div>
);
ReactDOM.render(appJsx, app);
就是通过{}将对jsx对象的引用变量放入即可,效果如下:
3.2 内联样式
在jsx中,可以直接使用内联样式,这和html中的使用是一样的,但是给style属性赋值的时候,是要传递一个对象的,这也就意味着我们需要像前面那样,使用{}将对象包裹起来,这样才能被jsx识别,对象可以是直接字面量写在jsx中,或者用变量引用一个对象传入也行
const main = (
<main style={{ backgroundColor: 'skyblue', fontSize: '24px' }}>
<p>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Facilis
animi, tempora tenetur eos commodi, veritatis atque qui obcaecati
reiciendis fugit nemo repellat architecto, impedit dolor aliquam
saepe illum ut nobis?
</p>
</main>
);
3.3 className
与html中直接定义class类名不同,jsx中定义类名要通过className属性,这是因为我们写的代码最终会被转成js,而class是js的关键字,如果在jsx中直接用class作为类名会导致冲突
现在我们给header元素添加一个类名
const header = (
<header className="header">
<h1>Hello JSX</h1>
</header>
);
再给这个类名添加样式
.header {
background-color: darkcyan;
}
3.4 注入数据给jsx
和前面组合多个JSX类似,我们可以还可以将别的变量注入到jsx中
3.4.1 注入string
可以将string注入到jsx中
// header 数据
const author = 'Plasticine';
const header = (
<header className="header">
<h1>Hello {author}</h1>
</header>
);
3.4.2 注入number
将number注入到jsx中
// main 数据
const likesCount = 666;
const main = (
<main style={{ backgroundColor: 'skyblue', fontSize: '24px' }}>
<p>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Facilis
animi, tempora tenetur eos commodi, veritatis atque qui obcaecati
reiciendis fugit nemo repellat architecto, impedit dolor aliquam
saepe illum ut nobis?
</p>
<p>likes: {likesCount}</p>
</main>
);
3.4.3 使用js表达式
事实上我们还可以在jsx中使用js表达式
const main = (
<main style={{ backgroundColor: 'skyblue', fontSize: '24px' }}>
<p>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Facilis
animi, tempora tenetur eos commodi, veritatis atque qui obcaecati
reiciendis fugit nemo repellat architecto, impedit dolor aliquam
saepe illum ut nobis?
</p>
<p>likes: {likesCount}</p>
<p>1 + 1 = {1 + 1}</p>
</main>
);
3.4.4 注入数组
可以直接将数组注入到jsx中
// footer 数据
const partners = ['mike', 'jack', 'plasticine'];
const footer = (
<footer>
<p>Copyright 2022</p>
<p>{partners}</p>
</footer>
);
但是很明显能看到,数据全都被放在一行显示了,不是很好看,我们可以利用数组对象的
map方法,将partners字符串数组转成jsx元素数组
const partners = ['mike', 'jack', 'plasticine'];
const partnersFormatted = partners.map((partner) => <li>{partner}</li>);
可以看到也渲染成功了, 但是控制台中会有警告
这里我猜测和
vue的v-for一样,对于数组的渲染,是需要一个key属性的,这涉及到底层对于元素更新的diff算法的优化
那么我们直接加上key属性就行了
const partnersFormatted = partners.map((partner) => (
<li key={partner}>{partner}</li>
));
这样就没有警告了
3.4.5 注入对象
对象就不能像数组那样直接注入了
// footer 数据
const partnerInfo = {
mike: '178cm',
jack: '180cm',
plasticine: '200cm',
};
const footer = (
<footer>
<p>Copyright 2022</p>
<p>{cooperativePartner}</p>
<p>{partnerInfo}</p>
</footer>
);
我们应当用对象中的具体值
const footer = (
<footer>
<p>Copyright 2022</p>
<p>{cooperativePartner}</p>
<p>mike: {partnerInfo.mike}</p>
<p>jack: {partnerInfo.jack}</p>
<p>plasticine: {partnerInfo.plasticine}</p>
</footer>
);
3.5 JSX中的注释
在JSX中,注释也要像变量一样注入进去,用{}包裹
const foo = (
{/* foo comment */}
<p>foo</p>
)
总结
第一天接触react,我们学习了:
- 如何创建和组合
jsx元素 - 如何在
jsx元素上使用内联样式 - 如何给
jsx元素添加类名 - 如何注入数据到
jsx元素中
可以感觉到,react的开发更加像是原生开发,也可以看出jsx的灵活性很强
今天只是简单体验上手一下react,使用cdn的方式可以明显感觉到开发体验并不好,比如没有语法提示,后面我们会通过脚手架的方式搭建react项目以及创建react组件,组件比jsx具有更强大的功能