一.简介
1.介绍
用于构建用户界面的 JavaScript 库
2.创建项目
(1)手动创建
<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>Document</title>
</head>
<body>
<!-- 加载 React。-->
<!-- 注意: 部署时,将 "development.js" 替换为 "production.min.js"。-->
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js" ></script>
<!-- 加载React 组件。-->
<!-- <script src="like_button.js"></script> -->
<div id="app"></div>
<!-- babel 编译为js代码 -->
<script type="text/babel">
// 创建元素, 虚拟DOM
const spanEle = React.createElement('span',{
name: 'title',
},'我是小span啦~')
const pEle = React.createElement('span',{
name: 'title',
},spanEle,spanEle) // 父元素中添加多个子元素, 通过,隔开 或者写一个数组
//类组件
class PComponent extends React.Component{
render(){
return(
<p>
<span>哈哈</span>
</p>
)
}
}
// 渲染组件
// ReactDOM.render(pEle,document.getElementById('app'))
ReactDOM.render(<PComponent />,document.getElementById('app'))
</script>
</bod
(2)使用脚手架创建及启动项目
npx create-react-app 项目名称
cd 项目名称
npm start
二.基本使用
1.JSX
(1)简介
const element = <h1>Hello, world!</h1>;
既不是字符串也不是 HTML。它被称为 JSX,是一个 JavaScript 的语法扩展。JSX 可以很好地描述 UI 应该呈现出它应有交互的本质形式,具有 JavaScript 的全部功能。
(2)简单使用
在JSX中嵌入表达式
JSX 也是一个表达式
特定属性
JSX 防止注入攻击
JSX 表示对象
<!-- html -->
<!-- babel 编译为js代码 -->
<script type="text/babel">
// 1. 在JSX中嵌入表达式 使用 { },其中写变量即可,也可调用函数
const name = '你好啊,我的空空!'
const element = <h1>在 JSX 中嵌入表达式 , {name}</h1>
// 2. JSX 也是一个表达式 可以在 if 语句和 for 循环的代码块中使用JSX,将 JSX 赋值给变量,把 JSX 当作参数传入,以及从函数中返回JSX
function getName(name) {
if (name !== '') {
return <h2>hhhh我是if语句块啦~~, {name}</h2>
}
return <h1>Hello, Stranger.</h1>
}
const ele = <div>{getName(name)}</div>
// 3. 特定属性
// 使用引号" " 将属性值指定为字符串字面量
const ele1 = <h2 tabIndex="0">哈哈</h2>
//使用大括号{ },在属性值中插入一个JavaScript表达式
const obj = {
imgUrl:'https://img2.baidu.com/it/u=2015865969,3401990894&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=546',
}
const ele2 = <img src={obj.imgUrl} />
const element2 = <div> === </div>
// 4. JSX 防止注入攻击 React DOM 在渲染所有输入内容之前,默认会进行转义, 所有的内容在渲染之前都被转换成了字符串。这样可以有效地防止 XSS(cross-site-scripting, 跨站脚本)攻击
const title = '啊哈哈哈'
// 直接使用是安全的:
const element3 = <h1>{title}</h1>
// 5. JSX 表示对象 Babel 会把 JSX 转译成一个名为 React.createElement() 函数调用
// 方式1
const element4 = <h1 className="greeting">Hello, world!</h1>
// 方式2 两种方式等效
const element5 = React.createElement(
'h1',
{ className: 'greeting' },
'Hello, world!'
)
/* 实际创建 注意:这是简化过的结构
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world!'
}
}; */
function test() {
return [element, ele, ele1, ele2, element2,element3,element4]
}
// 渲染组件
ReactDOM.render(test(), document.getElementById('app'))
</script>
2.元素渲染
React 只更新它需要更新的部分, 局部刷新, Diff算法
这里的代码在'3.组件&Props'中一起写着哦~
3.组件&Props
(1)组件
a.函数组件
// App.js
import './App.css';
import ClassComponets from './components/ClassComponents';
import SonComponets from './components/SonComponents'
// 函数组件
function App() {
return (
// 可使用空标签, <></> 相当于<template> 将标签包裹起来
<>
<ul>
<li> app1 </li>
<li> app2 </li>
<li> app3</li>
</ul>
<ClassComponets></ClassComponets>
{/* 向子组件传值 */}
<SonComponets></SonComponets>
<SonComponets title="这里是App.js向EleRenderComponets传递的title"></SonComponets>
</>
);
}
export default App;
b.Class类组件
//ClassComponents
//引入react
import { Component } from 'react'
// 创建类组件 必须继承react中的Component(导入) 如果未导入react, 直接继承React.Component即可
class ClassComponets extends Component{
// 渲染函数
render(){
return(
<>
<h1>哈喽a, 空空子!!!</h1>
</>
)
}
}
// 导出组件
export default ClassComponets
(2)Props
组件决不能修改自身的 props
所有 React 组件都必须像纯函数一样保护它们的 props 不被更改 (纯函数: 不修改传递进来的参数,且多次调用下相同的入参始终返回相同的结果)
//SonComponents.js
// 元素渲染
//引入react
import { Component } from 'react'
import SonSonComponents from './SonSonComponents'
// 创建类组件 必须继承react中的Component
class SonComponets extends Component{
// 构造器 参数props, 用于接收父组件传递的值 props是只读的,不可修改
constructor(props){
super(props)
// state 局部私有 但值可修改
this.state = {
time : new Date().toLocaleTimeString()
}
// 为了在回调中使用 `this`,这个绑定是必不可少的
this.updateTime = this.updateTime.bind(this);
}
// 更新状态
updateTime(){
this.setState({time : new Date().toLocaleTimeString()})
}
// 渲染函数
render(){
// 如果想在本组件的子组件中获取到本组件的父组件的值, 可使用解构
const { title } = this.props
return(
<>
<h1>Son哈哈哈</h1>
<h1>现在时间: { this.state.time }</h1>
<button onClick={this.updateTime}>更新时间</button>
{/* 父组件(App)向子组件传值 */}
<h3>App传递的值: {this.props.title}</h3>
{/* title2是本组件的父组件的值,传递给本组件的儿子 */}
<SonSonComponents title1="本组件=>儿子传" title2={title}></SonSonComponents>
</>
)
}
}
// 导出组件
export default SonComponets
// SonSonComponents.js
//引入react
import { Component } from 'react'
// 创建类组件 必须继承react中的Component
class SonSonComponets extends Component{
// 构造器 参数props, 用于接收父组件传递的值
constructor(props){
super(props)
}
// 渲染函数
render(){
return(
<>
<h1>SonSon哈哈哈</h1>
{/* 父组件(App)向子组件传值 */}
<h3>{this.props.title1}</h3>
<h3>{this.props.title2}</h3>
</>
)
}
}
// 导出组件
export default SonSonComponets
4.State&生命周期
// 元素渲染
//引入react
import { Component } from 'react'
// 创建类组件 必须继承react中的Component
class TimeComponets extends Component{
// 构造器 参数props, 用于接收父组件传递的值 props是只读的,不可修改
constructor(props){
super(props)
this.state = {
time : new Date().toLocaleTimeString()
}
}
// 钩子函数
// 挂载完成后, 已有dom元素
componentDidMount(){
// 挂载完成后执行, 只执行一次
console.log('componentDidMount');
//更新 state
this.timeTnterval = setInterval(()=>{
this.setState({time : new Date().toLocaleTimeString()})
},1000)
}
// 组件卸载之前 可进行清理内存,清除定时器
componentWillMount(){
clearInterval(this.timeTnterval)
}
// 渲染函数
render(){
return(
<>
<h1>~~~时间~~~</h1>
<h1>timeComponents---现在时间: { this.state.time }</h1>
</>
)
}
}
// 导出组件
export default TimeComponets
三.Hook
// Hook 组件
// Hook不能在class组件中使用, 可以在函数组件中使用
// Hook只能在函数最顶层调用, 不要在循环,条件判断或子函数中调用 在React函数的最顶层以及任何 return之前调用
import React,{useEffect, useState} from 'react'
function HookComponent(){
// 声明一个叫fruits的state变量 返回一对值: 当前状态和让更新它的函数 数组解构
const [fruits, setFruits] = useState('qqq') // const fruit = '' setFruits("abc")
const [num,setNum] = useState(0)
// 将componentDidMount, componentDidUpdate, componentWillUnMount 合并成一个Hook函数 [依赖项] 如果有依赖项(可有多个),当其中至少有一个依赖项发生变化时,才页面更新, 没有依赖项则每次数据变化页面都更新
useEffect(()=>{
document.title = `click-${num}-times`
},[fruits])
// 当页面首次渲染以及有更新的时候, 就先执行清理函数, 再执行函数内容(定时器)
useEffect(()=>{
let timer = setInterval(()=>{
console.log('在Hook中创建定时器')
},1000)
return ()=>{
console.log('在Hook中清理定时器')
// 清理副作用
clearInterval(timer)
}
})
return (
<>
<h1>{ fruits }</h1>
<p>
<button onClick={()=>setFruits('aaa')}>修改为aaa</button>
<button onClick={()=>setFruits('qqq')}>修改为qqq</button>
<button onClick={()=>setNum(num+1)}>click{num}</button>
</p>
</>
)
}
export default HookComponent
/* 使用箭头函数直接默认导出
export default ()=>{
} */
参考官方文档: https://react.docschina.org/
wo放了好多代码, 是不是因为描述太少, 官方提醒改进质量, 一些注释基本都在代码里边, 偷个小懒不想再单独写出来了呜呜呜, 在这废言凑凑字数叭~~~ 不得不说, 前端的官方文档还是写的都还是挺好的, 大家可以多参考参考文档哦~~~也帮我加加阅读量点赞量什么的呗( 求求~~~ )