React基础
什么是React
React是一个构建用户界面的JavaScript库,主要用来编写HTML页面或构建Web应用
React的特点
- 声明式
- 组件化
- 一次学习,随处编程
React的基本使用
1.安装命令 npm i react react-dom
react 是核心包,提供创建元素和组件能力
react-dom 负责将元素和组件渲染到界面
2.React使用
<body>
<!-- 创建React元素 -->
<div id="app"></div>
</body>
<!-- 导入react和react-dom两个js文件 -->
<script src="./node_modules/react/umd/react.development.js"></script>
<script src="./node_modules/react-dom/umd/react-dom.development.js"></script>
<script>
console.log(React);
console.log(ReactDOM);
//渲染React元素到页面中
// <h1 id="123">子节点</h1>
// createElement方法
// 第一个参数 创建元素
// 第二参数 元素上面有的属性
// 第三个参数 子节点
const title = React.createElement("h1",{
id:"123"
},"子节点")
// render
// 函数第一个参数是渲染的元素
// 函数第二参数是挂载点 document.getElementById("app")
ReactDOM.render(title,document.getElementById("app"));
</script>
注意:react-devlopment.js要在react-dom.development.js之前导入,否则报错
React JSX
JSX是一个JS的扩展,需要通过babel转换成浏览器能执行的js代码,可以在开发React应用时显示更多有用的错误提示和警告信息,提高开发体验
1.解析器的安装
安装命令:npm i babel-standalone
babel-standalone是JSX语法的解析器,通过它可以将JSX转换成浏览器能够执行的代码
<body>
<div id="app"></div>
</body>
<!-- 1. 将需要的依赖库引入 react react-dom babel-->
<script src="./node_modules/react/umd/react.development.js"></script>
<script src="./node_modules/react-dom/umd/react-dom.development.js"></script>
<script src="./node_modules/babel-standalone/babel.min.js"></script>
<!-- 2. 给script 脚本添加一个 type="text/babel"-->
<script type="text/babel">
const H1 = <h1 id="title" className="demo">我是一个大标题<p>内容</p> {new Date().toString()}</h1>;
ReactDOM.render(H1,document.getElementById("app"));
</script>
注意:JSX多个元素必须使用一个跟元素包裹起来,不然会报错
React脚手架搭建
1.脚手架的意义
- 脚手架是开发现代Web的必备工具
- 充分利用Webpack、Babel等工具辅助开发
- 关注业务,无需关注繁琐的工具配置
- Vue中的Vue-cli,React中的create-react-app都是脚手架
2.使用脚手架初始化React项目(create-react-app)
- 初始化项目命令:npx create-react-app my-app
- 启动项目步骤:1.cd my-app 2.npm run
start 或者 yarn start 启动项目
3.npx 命令介绍
- npm v5.2.0 引入的一条命令
- 目的:提升命令行工具的使用体验
- 原来:先安装脚手架全局包,再使用它初始化项目
- 现在:无需安装脚手架全局包,就可以直接使用它初始化项目
4.组件导出导入并使用
- 创建src/MyFirstReact.js
- 编写组件代码,创建想要的界面元素
- 导出组件
- 在src/App.js中导入并使用组件
MyFirstReact.js
//创建
import MyFirstReact from "./MyFirstReact"
function App() {
return (
<div className="App">
App 内容
<MyFirstReact></MyFirstReact>
</div>
);
}
//暴露
export default App;
App.js
import MyFirsReact from './MyFirsReact'
import './App.css'
function App() {
return (
<div className="App">
app内容
<MyFirsReact></MyFirsReact>
</div>
);
}
export default App;
JSX语法
1.JSX语法
JSX是JavaScript XML的简写,表示在JavaScript代码中编写HTML格式代码
优势:声明式语法更加简洁,与HTML结构相同,提高开发效率
- 基本用法
语法:{JavaScript表达式}
表达式中的数据存储在JS变量中 - JSX中使用JavaScript表达式
// jsx 中表达式
function App() {
const name = "Jack";
const sayHi = ()=>{
return "😀"
}
let obj = {
name:"Thomas"
}
let arr = ["1",1,<h1 key="1">123</h1>,"🍎","🍌"];
return (
<div>
你好,我叫:{name}
{/*数字*/}
<h1>{1}</h1>
{/*算术表达式*/}
<h1>{1+1}</h1>
{/*字符*/}
<h1>{"(*^_^*)"}</h1>
{/*调用函数*/}
<h1>{sayHi()}</h1>
{/*另外一个jsx*/}
<h1>{<p>另外一个jsx</p>}</h1>
{/*三目运算符*/}
{ 1>0?"真":"假"}
{/*语句 是不允许的*/}
{/* <h1>{ if(1>0)}</h1> */}
{/* <h1>{for(let i=0;i<0;i++){}}</h1> */}
{/*对象 是不允许的 界面报错
Error: Objects are not valid as a React child (found: object with keys {name}).
If you meant to render a collection of children, use an array instead.
*/}
{/* {obj} */}
{/* 数组 */}
{arr}
</div>
);
}
export default App
- JSX中的条件渲染
// if else 实现条件的渲染
// let is_login = true;
// function JSX() {
// if (is_login) {
// return (<div>
// <p>欢迎登录</p>
// </div>);
// }else{
// return (<p>请登录</p>)
// }
// }
// export default JSX;
// 三目运算符 实现 条件渲染
let is_login = false;
function JSX() {
return <div>
{is_login?<p>欢迎登录</p>:<p>请登录</p>}
</div>
}
export default JSX;
- JSX中的循环渲染
语法:{ 数组变量.map( item=>( <标签>{item}</标签> ) ) }
注意:map方法前面通常是数组,map方法的箭头函数体内容放到小括号中
key跟Vue中v-for中的key一个道理
function JSX() {
// let books = ["DOM编程艺术","JS高级编程","React 实战"];
let books = ["DOM编程艺术", "JS高级编程", "React 实战"];
// let arr = [<li>{books[0]}</li>, <li>{books[1]}</li>, <li>{books[2]}</li>];
// [<li>{book}</li>,<li>{book}</li>,<li>{book}</li>]
// let arr = books.map(book=>{
// return <li>{book}</li>
// })
// let arr = books.map(book=><li>{book}</li>)
return <ul>
{books.map(book=><li key={book}>{book}</li>)}
</ul>;
}
export default JSX;
- JSX中样式处理
- 行内样式
// React 中如何生成 行内样式
// style={{color:"red"}}
const App = () => {
return (
<div>
<h1 style={{color:"red",fontSize:"100px"}}>红色</h1>
</div>
);
}
export default App;
- 类名样式
import "./App.css"
const App = () => {
return (
<div>
{/*class => className */}
<h1 className="big">big</h1>
</div>
);
}
export default App;
注意:JSX中给元素设置css类名是className而非class,因为class是关键字
- 空标签
// JSX 表达式必须具有一个父元素
// vue =>template 小程序=>block
// Fragment 空标签
import {Fragment} from "react"
const App = () => {
return <Fragment>
<h1>123</h1><h1>123</h1>
</Fragment>
}
export default App;
- 注意点
JSX中如果有多个元素必须使用一个根元素包裹起来,通常是一个div作为根元素即可
特殊名称:class->className
jsx中不能直接使用if,for等语法结构
jsx中遍历通常使用 map方法,并且使用()包括起里边的jsx结构,否则会报错
分支结构通常使用三元表达式来实现
React组件基础
我们学习React其实就是学习组件的使用
组件是用来封装页面中某一部分功能的,例如:轮播图组件、底部tabBar组件、业务组件
多个组件的灵活组合可以实现不同的页面功能展示
- 两种创建组件的方式(函数组件和类组件)
使用JS函数创建组件(function Hello(){}和const Hello = ()=>{})
函数组件名称的首字母必须大写
函数组件必须有返回值,通常是返回JSX结构
如果返回是null,表示不渲染任何内容
// 函数式组件
// 1.function App(){} 或者是通过 const App=()=>{}
// 2.函数式组件中通常会返回一段 JSX
// 3.组件名通常情况下是大写的
// 4. return null 表示不渲染任何东西
// function App(){
// // return <div>jsx</div>
// return null;
// }
const App = ()=>{
return <div>jsx</div>
}
export default App;
使用类创建组件(类组件)
使用ES6的class创建组件
类组件名称的首字母必须大写
类组件必须继承React.Component父类,因为父类中实现了一些通用的公共属性(state)和生命周期方法
类组件必须有render()方法,并且通常返回一个JSX结构表示要显示的组件页面结构
// 类组件
// 1. es6 class 定义的,组件名必须大写
// 2. 继承 React.Component 或者 React.PureComponent
// 3. 类中,必须实现一个 render 方法,返回一段JSX
import React from "react"
class App extends React.Component{
render(){
return <div>
<h1>这是一个类组件</h1>
</div>
}
}
export default App;
- React事件处理和this问题
语法:on+事件名称={事件处理函数} 例如:onClick={()=>{}}
注意:React事件名称的on是小写,后面跟着的事件描述单词间首字母大写,例如:onChange、onMouseMove
函数组件中事件绑定
function App(){
console.log(this);// undefined
// 2. 定义了一个处理函数
const handleClick = ()=>{
console.log(this);
console.log("点击了");
}
return (<div>
{/*1. 通过onClick 注册一个点击事件*/}
<button onClick={handleClick}>点击我啊触发</button>
</div>)
}
export default App;
类组件中事件绑定
// 注册一个 onClick 事件
// 1. 引入 React 核心库
import React from "react"
class App extends React.Component{
// 2. 定义一个类属性 等于 一个箭头函数
handleClick = ()=>{
console.log("点击事件触发了");
}
// msg="123"
// 3. 定义一个render 函数
render(){
console.log(this);
return (<div>
{/* on+事件的名称 = {处理函数}*/}
<button onClick={this.handleClick}>点击我啊</button>
<button onClick={()=>{
this.handleClick();
}}>点击我啊(箭头函数)</button>
{/* <button onClick={this.handleClick()}>点击我啊(错误的例子)</button> */}
</div>)
}
}
export default App;
this指向问题
import React from "react"
class App extends React.Component{
// 1. 定义一个类属性 msg
msg="我是一个消息";
// 2. 定义一个类函数 handleClick
handleClick(){
console.log(this);
// TypeError: Cannot read property 'msg' of undefined
console.log(this.msg);
}
// 3. 定义一个render 函数
render(){
return <div>
{/*4. 定义一个点击事件*/}
<button onClick={this.handleClick}>点击,获取类属性中的msg</button>
</div>
}
}
// 5 导出 App 组件
export default App;
3种解决方案
// this 指向
// 类 的 事件绑定
// 解决this指向的问题 三种方法
import React from "react"
class App extends React.Component{
// constructor(props){
// // 1. 修正this 指向的第一种方式 在构造函数中通过 bind 改变 this 的指向
// super(props)
// this.handlClick = this.handlClick.bind(this)
// }
name='jack'
// handlClick(){
// // TypeError: Cannot read property 'name' of undefined
// console.log(this.name);
// }
// 第三把事件该为箭头函数 也是推荐用法
handlClick=()=>{
console.log(this.name);
}
render(){
// return <div><button onClick={this.handlClick}>类中的事件绑定</button></div>
// 修正 this 指向第二中方式 定义的时候 通过 bind 绑定 this
// return <div><button onClick={this.handlClick.bind(this)}>点击获取name的值(bind改变this指向)</button></div>
// return <div><button onClick={()=>{this.handlClick()}}>点击获取name的值</button></div>
return <div><button onClick={this.handlClick}>点击获取name的值(箭头函数改变this指向)</button></div>
}
}
export default App;