React的概述
- React 是一个用于构建用户界面的 JavaScript 库。
- 从 MVC 的角度来看,React 仅仅是视图层(V),也就是只负责视图的渲染,而并非提供了 完整的 M 和 C 的功能。
React的特点
- JXS语法是声明式的,只需要描述页面的结构,使得我们可以在JS文件中直接书写HTML标签。
- 可以创建一些拥有自己状态的组件,再使用这些组件去构成更加复杂的组件,在页面中渲染出来。
- 不单是在Web开发中可以使用React,在一些安卓应用和ios应用开发上也可以使用。
React的基本使用
- 代码
<!-- 创建根标签 -->
<div id="root"></div>
<!-- 引入两个JS文件 -->
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<script>
// 创建React虚拟DOM
// 参数一:需要创建的元素名
// 参数二:创建元素的属性,这里面为了防止和一些关键字冲突,建议将class换为className,label的for属性改成htmlFor,虽然这样写还是能渲染出来
// 参数三和之后的参数:子节点,比如文本节点或者是React元素
const title = React.createElement('h1', null, 'Hello React')
// 将虚拟DOM插入到根标签中渲染
ReactDOM.render(title, document.getElementById('root'))
</script>
- 实现
JSX
- JavaScript XML,是React提供的语法糖
- 代替了React.createElement(),可以更简洁的去书写React元素,
- 由于浏览器识别不出JSX,所以需要引用一个将JSX解析成React.createElement()的包——babel
简单使用
<div id="root"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<script src="https://cdn.bootcdn.net/ajax/libs/babel-standalone/6.21.0/babel.min.js"></script>
<!-- script标签的type属性需要设置 -->
<script type="text/babel">
// 创建
const h1 = <h1 className='h1'>Hello React</h1>
// 渲染
ReactDOM.render(h1, document.getElementById('root'))
</script>
条件渲染
-
if条件判断
// if判断 // 创建 let h1 if (flag) { h1 = <h1 display='block'>Hello React</h1> } else { h1 = <h1 display='block'>Hello React</h1> } // 渲染 ReactDOM.render(h1, document.getElementById('root')) -
三元运算符
// 三元判断 // 创建 let h1 = flag ? <h1 display='block'>Hello React</h1> : <h1 display='block'>Hello React</h1> // 渲染 ReactDOM.render(h1, document.getElementById('root')) -
&运算符
// &运算 // 创建 let h1 = flag && <h1 display='block'>Hello React</h1> // 渲染 ReactDOM.render(h1, document.getElementById('root'))
列表渲染
- ReactDOM.render中可以直接渲染数组
- 推荐使用数组的map方法,将标签放入到数组中去,然后渲染出来
- 渲染出来的列表项应该加上key属性
let arr = [
{
name: '孙悟空'
},
{
name: '猪八戒'
},
{
name: '沙僧'
}
]
arr = arr.map((item, index) => {
return <li key={index}>{item.name}</li>
})
console.log(arr)
ReactDOM.render(arr, document.getElementById("root"))
事件处理
绑定事件
// 直接在标签中书写事件
const button = <button onclick={() => { }}></button>
注意点:
- 事件命名采用小驼峰命名法
- 事件中书写事件处理函数,而不是字符串
事件对象
在React中,事件对象称为合成事件
注意点:
- 在在事件处理函数中,不能使用return false来阻止默认事件,而是使用事件对象的preventDefault()来实现
- 在控制台直接打印出事件对象,属性值都是null,如果需要查看使用对象的persist()方法
React的组件
组件是将每个UI拆分成多个独立的模块,可以对每个模块独立开发
组件的种类
-
函数组件
import React from 'react' export default function Header() { return ( <div> 1.这是函数组件,函数组件中不能定义状态 2.组件名要大写开头,函数的必须要有返回值,返回值是函数组件要呈现的结构,如果返回null则表示不渲染 3.组件中,可以创建多个标签,但是必须要使用一个根标签包裹,组件中只能有一个根标签 </div> ) } -
类组件
import React, { Component } from 'react' export default class Header extends React.Component { render() { return ( <div> 1.这是类组件,类组件中可以定义状态 2.类组件继承了React.Component父类,可以使用父类的方法或属性 2.类组件中必须声明一个render函数 3.render函数需要有一个返回值,将需要呈现出来的结构返回出去 4.组件中,可以创建多个标签,但是必须要使用一个根标签包裹,组件中只能有一个根标签 </div> ) } }
组件的state
组件的状态(state),组件内部的私有数据,state是一个对象,里面可以保存多条数据
-
设置state
//设置方法一 export default class Header extends React.Component { state = { count: 1 } render() { return ( <div></div> ) } } //设置方法二 export default class Header extends React.Component { // 在constructor中设置状态 constructor() { super() this.state = { count: 1 } } render() { return ( <div></div > ) } } -
获取state
//通过this.state获取到组件内部的状态 export default class Header extends React.Component { constructor() { super() this.state = { count: 1 } } render() { return ( <div>{this.state.count}</div > ) } } -
操作state
export default class Header extends React.Component { constructor() { super() this.state = { count: 1 } } render() { return ( <div> <button onClick={() => { this.setState({ count: this.state.count + 1 }) }}>点击增加数量 </button> </div > ) } }
类组件中this指向问题
export default class Header extends React.Component {
render() {
return (
<div>
<button onClick={function () {
console.log(this)//指向undefined
}}>点击打印this
</button>
</div >
)
}
}
-
问题分析:函数在默认调用的情况下,应该是指向window,但是在React中,JSX通过babel进行编译时,执行的是严格模式,所以导致this指向undefined。
-
解决方法:
- 箭头函数
// 箭头函数解决this export default class Header extends React.Component { render() { return ( <div> <button onClick={() => { //由于箭头函数没有自己的this,是在定义时候确定的,所以指向当前组件实例 console.log(this) }}>点击打印this </button> </div > ) } }- bind绑定
export default class Header extends React.Component { constructor() { super() // 因为构造器中的this指向的是组件实例,所以可以通过bind直接将handle函数的this绑定到实例上 this.handle = this.handle.bind(this) } handle() { console.log(this) } render() { return ( <div> <button onClick={this.handle}> 点击打印this </button> </div > ) } }- 直接加在组件实例上
// 类的实例方法 export default class Header extends React.Component { // 在组件实例上直接添加事件处理函数,this也是指向组件实例 handle = () => { console.log(this) } render() { return ( <div> <button onClick={this.handle}> 点击打印this </button> </div > ) } }
组件的props
父组件可以向子组件中传递数据,子组件通过this.props来接收数据
-
使用
- 父组件传递数据
export default class App extends Component { state={ name:'lily', age:18 } render() { return ( <div> {/* 父组件可以通过属性的方式向子组件传递自己组件内部的state */} <Header msg={this.state}></Header> </div> ) } }- 子组件接收数据
export default class Header extends React.Component { render() { // 解构出父组件state中的name和age的值 const { name, age } = this.props.msg console.log(name, age)//lily 18 return ( <div></div > ) } }