React
一、React介绍与配置
1、React是什么
React由Meta公司研发,是一个用于构建Web和原生交互界面的库
2、开发环境搭建
(1)使用create-react-app快速搭建开发环境
create-react-app是一个快速创建React开发环境的工具,底层由Webpack构建,封装了配置细节,开箱即用。
执行命令:
npx create-react-app@latest 项目名
①npx Node.js工具命令,查找并执行后续的包命令
②create-react-app 核心包(固定写法),用于创建React项目
创建React项目的更多方式
(2)初始化生成项目
index.js中
// 项目入口
// Reat必要的两个核心包
import React from 'react';
import ReactDOM from 'react-dom/client';
// 导入项目根组件
import App from './App';
// 把App根组件渲染到id为root的dom节点上
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<App />
);
App.js中
// 项目根组件
function App() {
return (
<div className="App">
this is App
</div>
);
}
export default App;
清理完成
二、JSX基础
1、概念和本质
(1)概念
JSX是JS和XML的缩写,表示在JS代码中编写HTML模板结构,它是React中编写UI模板的方式
优势:①HTML的声明式模板写法 ②JS的可编程能力
(2)本质
JSX并不是标准的JS语法,它是JS的语法扩展,浏览器本身并不能识别,需要通过解析工具做解析后才能在浏览器中运行。
2、高频场景
JSX中使用JS表达式
在JSX中可以通过打括号{}识别JS中的表达式,比如常见的变量、函数调用、方法调用等。
①使用引号传递字符串
②使用JS变量
③函数调用和方法调用
④使用JS对象
// 项目根组件
const count = 100
function getName(){
return 'Alastor'
}
function App() {
return (
<div className="App">
this is react
{/* 使用引号传递字符串 */}
{'this is message'}
{/* 识别js变量 */}
{ count }
{/* 函数调用 */}
{ getName() }
{/* 方法调用 */}
{ new Date().getDate() }
{/* JS对象 */}
<div style = {{color:'pink'}}>这是一个div</div>
</div>
);
}
export default App;
3、JSX中实现列表渲染
(1)基本实现
语法:在JSX中可以使用原生js中的map方法遍历渲染列表
const list = [
{id:1,name:'a'},
{id:2,name:'b'},
{id:3,name:'c'}
]
function App() {
return (
<div className="App">
{/* 渲染列表 */}
{/* 注意事项:加一个独一无二的key 字符串或number id */}
{/* key作用:React框架内部使用 提升更新性能 */}
<ul>
{list.map(item=><li key = {item.id}>{item.name}</li>)}
</ul>
</div>
);
}
(2)条件渲染
语法:在React中,可以通过逻辑与运算符&&、三元表达式(?:)实现基础的条件渲染
{/* 条件渲染 */}
{flag&&<span>这是个span</span>}
{loading ? <span>正在加载</span> : <span>这是个span</span>}
(3)实现复杂条件渲染
需求:列表中需要根据文章状态适配三种情况:单图、多图、无图三种模式
解决方案:自定义函数+if判断语句
// 复杂条件渲染
// 定义文章类型
const articleType = 1 // 0 1 3 无图 单图 三图
// 定义核心函数,根据文{章类型返回不同JSX模板
function getArticleTem(){
switch(articleType){
case 0 :
return <div>无图文章</div>
case 1 :
return <div>单图文章</div>
case 3 :
return <div>三图文章</div>
default:
return <div>默认渲染</div>
}
}
function App() {
return (
<div className="App">
{/* 复杂条件渲染 */}
{/* 使用函数渲染不同的模板 */}
{ getArticleTem(1) }
</div>
);
}
三、事件绑定
1、基础事件绑定
语法:on+事件名称={事件处理程序}
整体上遵循驼峰命名法
注:使用事件对象参数时,在事件回调函数中设置形参e
// 事件绑定
function clickHandler(e){
console.log('点击了按钮',e);
}
function App() {
return (
<div className="App">
{/* 事件绑定 */}
<button onClick = { clickHandler }>这是个按钮</button>
</div>
);
}
2、传递自定义参数
语法:事件绑定的位置使用箭头函数,执行clickHadler实际处理业务时传递实参
// 传递自定义参数
function clickHandler2(name){
console.log('点击了按钮',name);
}
function App() {
return (
<div className="App">
{/* 传递实参 */}
<button onClick = { ()=>clickHandler2('jack') }>这是按钮2</button>
</div>
);
}
注意:不能直接写函数调用,这里事件绑定需要一个函数引用
3、同时传递事件对象和自定义参数
语法:在事件绑定的位置传递事件实参e和自定义参数,clickHandler中声明形参,注意顺序对应。
// 同时传递事件对象和自定义参数
function clickHandler3(name,e){
console.log(name,e);
}
function App() {
return (
<div className="App">
{/* 同时传递事件对象和自定义参数 */}
<button onClick = { (e)=>clickHandler3('jack',e) }>这是按钮3</button>
</div>
);
}
四、组件
1、概念
一个组件就是用户界面的一部分,它可以有自己的逻辑和外观,组件之间可以互相嵌套,也可以复用多次。
组件化开发可以让开发者像搭积木一样构建一个完整庞大的应用。
2、React组件
在React中,一个组件就是首字母大写的函数,内部存放了组件的逻辑和视图UI,渲染组件只需要把组件当成标签书写即可。
// 定义组件
function Button(){
// 业务逻辑
return <button>点我</button>
}
function App() {
return (
<div className="App">
{/* 使用组件 */}
{/* 自闭和 */}
<Button/>
{/* 成对 */}
<Button></Button>
</div>
);
}
五、UseState
1、概念
一个React Hook(函数),它允许我们向组件添加一个状态变量,从而控制影响组件的渲染结果。
本质:和普通js变量不同的是,状态变量一旦发生变化,组件的视图UI也会跟着发生变化(数据驱动视图)
// useState实现计数器
import { useState } from 'react'
function App() {
// 1、调用useState添加一个状态变量
// count 状态变量
// setCount 修改状态变量的方法
const [count,setCount] = useState(0)
// 2、点击事件回调
const handleClick = ()=>{
setCount(count+1)
}
return (
<div className="App">
<button onClick={handleClick}>{count}</button>
</div>
);
}
export default App;
注:
①useState是一个函数,返回值是一个数组
②数组中的第一个参数是状态变量,第二个参数是set函数用来修改状态变量
③useState的参数将作为count的初始值
2、修改状态的规则
(1)状态不可变
在React中,状态被认为是只读的,我们应该始终替换它而不是修改它,直接修改不能引发视图更新。
setCount(count+1)
始终调用setCount方法,并传入一个新值
(2)对象类型
规则:对于对象类型的状态变量,应该始终传给set方法一个全新的对象来进行修改
function App() {
// 对象类型的状态变量
const [form,setForm] = useState({
name: 'Alastor'
})
const handleChangeName = ()=>{
setForm({
...form,
name: 'john'
})
}
return (
<div className="App">
<button onClick={handleChangeName}>修改状态{form.name}</button>
</div>
);
}
六、组件的样式处理
1、组件基础样式方案
React组件基础的样式控制用两种方式
(1)行内样式(不推荐)
{/* 1、行内样式(不推荐) */}
<div style={{color: 'red'}}>这是个div</div>
(2)class类名控制
import './00-组件样式.css'
{/* 2、class类名控制 */}
<div className= 'foo'>这也是个div</div>
.foo{
color: pink;
}
七、受控表单受绑定
1、概念
使用React组件状态(useState)控制表单的状态(类似于v-model)
(1)准备一个React状态值
(2)通过value属性绑定状态,通过onChange属性绑定状态同步的函数
import { useState } from 'react'
function App() {
// 1、准备一个React状态值
const [value,setValue] = useState('')
return (
<div className="App">
{/* 2、通过value属性绑定状态,通过onChange属性绑定状态同步的函数 */}
<input
type="text"
value={{value}}
onChange={(e)=>{setValue(e.target.value)}}
></input>
</div>
);
}
export default App;
2、React中获取DOM
在React组件中获取/操作DOM,需要使用useRef钩子函数,分为两步:
(1)使用useRef创建ref对象,并于jsx绑定
(2)在DOM可用时,通过inputRef.current拿到DOM对象
import { useRef } from 'react'
// 1、useRef生成ref对象,绑定到dom标签身上
// 2、dom可用时,ref.current获取dom
function App() {
const inputRef = useRef(null)
const showDom = function(){
console.log(inputRef.current);
}
return (
<div className="App">
<input type = "text" ref={inputRef}></input>
<button onClick={showDom}>log获取的DOM</button>
</div>
);
}
export default App;
八、组件通信
组件通信就是组件之间的数据传递,根据组件嵌套关系的不同,有不同的通信方法
1、父传子
(1)父传子实现
实现步骤
①父组件传递数据-在子组件标签上绑定属性
②子组件接收数据-子组件通过props参数接收数据
// 父传子
// 1、父组件传递数据 子组件标签绑定属性
// 2、子组件接收数据 props参数
function Son(props){
// props:该对象里面包含了父组件传递的所有数据
return <div>这是子组件,父组件name:{props.name}</div>
}
function App() {
const name = '这是父组件'
return (
<div className="App">
<Son name = {name}></Son>
</div>
);
}
export default App;
(2)props说明
①props可传递任意的数据
数值、字符串、布尔值、数组、对象、函数、JSX
<Son
name = {name}
age = {18}
isTrue = {false}
list = {['vue','react']}
obj = {{name:'Alastor'}}
cb = {()=>{console.log('123');}}
child = {<span>这是个是span</span>}
></Son>
②props是只读对象
子组件只能读取props中的数据,不能直接进行修改,父组件的数据只能由父组件修改
(3)特殊的prop-childrten
场景:当我们把内容嵌套在子组件标签的时候,父组件会自动在名为children的prop属性中接收该内容
<Son>
<span>这是个span</span>
</Son>