第一节:react简介和入门用法
一. react简介
1. 说明
用于构建用户界面的 JavaScript 库 ( 官网: https://react.docschina.org/ ),React由Facebook来更新和维护,它是大量优秀程序员的思想结晶:
(1). React的流行不仅仅局限于普通开发工程师对它的认可;
(2). 大量流行的其他框架借鉴React的思想;
2. 哪些公司在用
阿里云、哔哩哔哩、快手、小米
二. 入门
1. 开发依赖的库
(1) react:包含react所必须的核心代码
(2) react-dom:react渲染在不同平台所需要的核心代码
(3) babel:将jsx代码转换成React代码的工具
PS:在React的0.14版本之前是没有react-dom这个概念的,所有功能都包含在react里, 那么为什么要拆分呢?
原因就是react-native:
(1). react包中包含了react web和react-native所共同拥有的核心代码。
(2). react-dom针对web和native所完成的事情不同:
✓ web端:react-dom会将jsx最终渲染成真实的DOM,显示在浏览器中
✓ native端:react-dom会将jsx最终渲染成原生的控件(比如Android中的Button,iOS中的UIButton)
<body>
<div id="root"></div>
<!-- 三个依赖 -->
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
// React18之后的写法
// const root = ReactDOM.createRoot(document.querySelector('#root'));
// root.render(<h2>hello react</h2>);
// React18之前的写法
ReactDOM.render(<h2>hello react</h2>, document.querySelector('#root'));
</script>
</body>
2. Babel和React的关系
通过Babel工具,将ES6转成大多数浏览器都支持的ES5的语法
(1) 默认情况下开发React其实可以不使用babel, 但是前提是我们自己使用 React.createElement 来编写源代码,它编写的代码非常的繁琐和可读性差。
(2) 那么我们就可以直接编写jsx(JavaScript XML)的语法,并且让babel帮助我们转换成React.createElement。
3. 普通开发
(1). 声明变量→封装事件→封装渲染函数→调用函数
PS:这里我们编写React的script代码中,必须添加 type="text/babel",作用是可以让babel解析jsx的语法
(2). createRoot函数:用于创建一个React根,之后渲染的内容会包含在这个根中
(3). 可以通过{}语法来引入外部的变量或者表达式
代码分享
<body>
<div id="root"></div>
<!-- 引入三个必备库 -->
<script src="../lib/react.js"></script>
<script src="../lib/react-dom.js"></script>
<script src="../lib/babel.js"></script>
<script type="text/babel">
const root = ReactDOM.createRoot(document.querySelector("#root"));
// 1. 声明变量
let msg = 'hello word';
// 2. 封装事件
function MyClick() {
// 修改数据
msg = 'hello react';
// 重新渲染
MyRender();
}
// 3. 封装一个渲染函数 (onClick 必须大写)
function MyRender() {
root.render(
<div>
<h2>{msg}</h2>
<button onClick={MyClick}>修改信息</button>
</div>
);
}
// 4. 调用函数
MyRender();
</script>
</body>
4. 组件化开发
4.1 步骤
(1). 我们知道root.render 参数是一个HTML元素或者一个组件,可以先将之前的业务逻辑封装到一个组件中,然后传入到 ReactDOM.render 函数中的第一个参数。
(2). 定义一个类(类名大写,组件的名称是必须大写的,小写会被认为是HTML元素),继承自React.Component
(3). 构造函数constructor
(4). 实现当前组件的render函数
✓ render当中返回的jsx内容,就是之后React会帮助我们渲染的内容
4.2 如何处理数据?
(1).存放数据:构造函数中 this.state = {定义的数据}
(2).修改数据:调用方法 this.setState({}) 用来修改数据,执行该方法后,会自动重新调用render函数。
4.3 如何处理事件绑定中的this?
(1). 剖析:
类中直接定义一个函数,并且将这个函数绑定到元素的onClick事件上,当前这个函数的this指向的是undefined。
原因:严格模式下,默认调用的this指向undefined,而babel转换代码,默认是开启严格模式的。
(2). 如何解决
方案A. 直接在标签中手动绑定: <button onClick={this.btnClick.bind(this)}>改变文本</button>
方案B. 在构造函数constructor中提前绑定: this.btnClick = this.btnClick.bind(this);
方案C: 回调函数
后面章节会完整分析(详见 jsx的事件绑定部分)
代码分享
<body>
<div id="root"></div>
<!-- 引入三个必备库 -->
<script src="../lib/react.js"></script>
<script src="../lib/react-dom.js"></script>
<script src="../lib/babel.js"></script>
<script type="text/babel">
// 1. 声明组件(类组件的模式)
class App extends React.Component {
//1.1 构造函数
constructor() {
super();
// 数据放到state里
this.state = { msg: 'hello word', name: 'ypf', age: 18 }
// 写法1:提前绑定,解决this为undefined的问题
this.btnClick = this.btnClick.bind(this);
}
//1.2 组件方法
btnClick() {
console.log('btnClick', this);
this.setState({ msg: 'hello react' });
}
//1.3 渲染方法
render() {
return (
<div>
<h2>{this.state.msg}</h2>
<button onClick={this.btnClick}>修改信息</button>
</div>
);
}
// 写法2: 解决this为undefined的问题
// render() {
// return (
// <div>
// <h2>{this.state.msg}</h2>
// <button onClick={this.btnClick.bind(this)}>修改信息</button>
// </div>
// );
// }
}
// 2. 把组件渲染到页面上
const root = ReactDOM.createRoot(document.querySelector('#root'));
root.render(<App />)
</script>
</body>
三. 相关案例
1 电影列表
3种写法
代码分享
<script type="text/babel">
// 1. 声明组件
class App extends React.Component {
// 1.1 构造函数
constructor() {
super();
this.state = {
movies: ["星际穿越", "流浪地球", "独行月球", "大话西游", "火星救援"]
}
}
// 1.2 渲染方法
render() {
// 写法1 (加个key,防止报警告)
// let movieList = [];
// this.state.movies.forEach((item, index) => {
// let liEle = <li key={index}>{item}</li>;
// movieList.push(liEle);
// });
// 写法2
// let movieList = this.state.movies.map((item, index) => <li key={index}>{item}</li>);
// return (
// <div>
// <h2>电影列表</h2>
// <ul>{movieList}</ul>
// </div>
// );
//写法3(直接写在jsx中)
return (
<div>
<h2>电影列表</h2>
<ul>{this.state.movies.map((item, index) => <li key={index}>{item}</li>)}</ul>
</div>
);
}
}
// 2. 将组件渲染到页面上
const root = ReactDOM.createRoot(document.querySelector("#root"));
root.render(<App />)
</script>
2 计数器
详见代码
代码分享
<script type="text/babel">
// 1. 声明组件
class App extends React.Component {
// 1.1 构造函数
constructor() {
super();
this.state = {
title: '计数器',
counter: 100
}
}
// 1.2 渲染方法
render() {
return (
<div>
<h2>{this.state.counter}</h2>
<button onClick={this.increase.bind(this)}>加1</button>
<button onClick={this.decrement.bind(this)}>减1</button>
</div>
);
}
// 实例方法
increase() {
this.setState({ counter: ++this.state.counter })
}
decrement() {
this.setState({ counter: --this.state.counter })
}
}
// 2. 将组件渲染到页面上
const root = ReactDOM.createRoot(document.querySelector("#root"));
root.render(<App />)
</script>
!
- 作 者 : Yaopengfei(姚鹏飞)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 声 明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
- 声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。