摘要
本篇主要是react基础篇。
- 项目创建
- jsx
- 事件
- 组件
- useState响应式变量
- 样式控制
react项目环境创建
利用cli可以快速搭建,react的cli工具叫:create-react-app,底层是基于webpack构建的,封装了配置细节,开箱即用。
-
执行
npx create-react-app yourProjectName
-
npm run start 运行模板项目
-
清理不需要的文件,以及修改删减核心入口代码。
保留 public/src/index.js/app.js/package.json/lock/reamdme/gitignore文件,其他生成的文件可以删除。
修改index.js代码:
保留5行即可
// react 2个核心包导入
import React from 'react'
import ReactDOM from 'react-dom/client'
// 根组件
import App from './App'
// 拿到public/index.html 里的root 节点
const root = ReactDOM.createRoot(document.getElementById('root'))
// 把根组件挂载到root节点上后进行render渲染
root.render(<App/>)
jsx
jsx = js + html 的缩写。是自创的一种写法,既然是二者的结合,也就具备二者的优点。
它是react中编写UI模板的方式。在js中写html结构。
在jsx中是通过 {}
大括号来识别js的表达式的。如:变量、函数调用、js对象、字符串等。
jsx可以识别的东西:
function App(){
return(
<div>
字符串:{'this is string'}
变量:{count}
函数调用:{getName()}
内置方法调用:{new Date().getDate()}
使用js对象<span style={{color:'#000'}}>span</span>
</div>
)
}
注意
if、for、Switch、变量声明等 属于语句的东西,是不能出现在{}里的,他只认识表达式!
优点
-
享有html声明式的模板写法。
-
享有js可编程的能力。
ps: 遇到dom标签用圆括号包裹,遇到js表达式用花括号包裹。
jsx本质
我们可以使用babel在线工具,写一段jsx,然后发现实际会转成jsx函数来调用,多层dom嵌套,就会有 多层的jsx函数嵌套来调用。
jsx如何写一个列表呢?
使用原生的map方法,循环哪个结构,return哪个结构,加上独一无二的key 是string 或者number类型。
return(
<ul>
{list.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
)
jsx中实现条件渲染
可以使用原生的 逻辑与
&& 或者 三元表达式 ?:
- 控制一个元素的显隐:
&&
{flag && <span>一个元素</span?}
- 控制2个元素的显隐:
?:
{flag ? <span>1号元素</span> : <span>2号元素</span>}
- 控制多个元素的显隐:需要利用函数来分流返回不同的模板。
function chooseTpl(flag){
if(flag == 1){
return <div>tpl1</div>
}else if(flag ==2 ){
return <div>tpl2</div>
}else{
return <div>tpl3</div>
}
}
事件绑定
1. 事件绑定
<button onClick={clickFn}>点击</button>
本文演示的代码案例均是核心代码片段,采用的都是函数式组件的写法。完整的代码机构基本如下:
function YourSelfComponent(){
const clickFn = ()=>{console.log('点击回调')}
return(
<div className="YourSelfComponent">
<button onClick={clickFn}>点击</button>
</div>
)
}
2. 获取事件对象e:
直接在函数定义位置,写 一个参数e来接收即可使用。
const clickFn = (e)=>{console.log('点击回调',e)}
3. 如果想传递自定义参数呢?
做编辑,删除时候常用。
绑定处,注意要改成箭头函数的写法,在执行回调实际处理业务函数的时候传递实参。
function YourSelfComponent(){
const clickFn = (mode)=>{console.log('弹窗模式',mode)}
return(
<div className="YourSelfComponent">
<button onClick={()=> clickFn('edit')}>编辑</button>
</div>
)
}
注意: 不能直接写函数调用,这里事件绑定需要一个函数引用。
4. 如果想用 事件对象e 还想要 自定义参数呢?
function YourSelfComponent(){
const clickFn = (mode,e)=>{console.log('弹窗模式',mode,'事件对象',e)}
return(
<div className="YourSelfComponent">
<button onClick={()=> clickFn('edit',e)}>编辑</button>
</div>
)
}
依然在绑定处使用箭头函数,然后参数传入和接收保持住一直的顺序。
组件
组件是一个通用的概念 哪个 框架里基本都有 组件化开发模式,它是不挑框架的。
概念:
一个组件就是一个页面的一个部分,它可以有自己的逻辑、外观,组件之间可以互相嵌套、也可以复用多次。
意义:
组件化开发可以让开发过程像 搭建积木一样构建一个完整庞大的应用。
分类:
通常在实际项目中,我们可能会把组件分为 "智能组件" 和 "UI组件"
-
智能组件: 负责数据的获取。
-
UI组件: 负责数据的渲染。组件本身就是单纯的UI,里面展示什么数据,你是外界传入的。
React组件
在React中,组件首字母是需要大写的,它是一个函数,内部存放了组件的逻辑和UI。
渲染组件只需要把组件当成标签书写即可。
useState
是一个react hook函数,它允许我们向组件添加一个状态变量,从而控制影像组件的渲染结果。
本质:
和普通js变量不同的是,状态变量具有响应性,状态变量发生变化后,组件的视图是会同步更新变化的。
也就是数据驱动视图
。
const [num,setNum] = useState(0)
特性:
- useState 是一个函数,返回值是一个数组。
- 数组中的第一个参数是状态变量,第二个参数是set函数,用来修改状态变量的
- useState的参数将作为num的初始值。
使用useState实现一个计数功能
import {useState} from 'react'
function App(){
//1.调用useState添加一个状态变量,num 是状态变量,setNum是修改状态变量的方法
const [num,setNum] = useState(0)
// 2. 点击 +1
const clickFn = ()=>{
setNum(num + 1)
// num++ //错误
}
return(
<button onClick={clickFn}>{num}</button>
)
}
useState的修改规则
请记住 状态不可变性
。
不可变性具体是指 直接修改状态变量 ,是不会引发视图的更新的,也就是没有响应性的。必须通过调用配套的set方法,然后传入一个新值,react内部会用这个新值来替换掉旧值,从而引发视图更新。
如:我们把 setNum(num + 1)
写成 num++
发现虽然num的值修改成功了,但是视图干脆不更新,
那么对于,对象来说呢,也是一样的道理,直接修改对象里的某个属性也是不生效的。react里推崇的思想是:
状态变量 不可修改,而是直接用新值做覆盖,才能更新!
对象类型的状态变量也是一样的规则:
import {useState} from 'react'
function App(){
//1.调用useState添加一个状态变量,num 是状态变量,setNum是修改状态变量的方法
const [dog,setDog] = useState({name:'jinmao',age:2})
// 2. 点击 +1
const clickFn = ()=>{
//直接修改,❌
// dog.name = 'jingba'
// 传入一个全新对象去覆盖,✅
setDog({
...dog,
name:'jingba'
})
}
return(
<button onClick={clickFn}>{num}</button>
)
}
样式
react组件基础样式控制方式有两种方式:
方式一:行内样式(不推荐)
<div style="{{color:'#000'}}">div</div>
第一层括号,是识别js语法用的,第二层括号是一个json对象,里面一个个key,value键值对。多单词有连字符的改成驼峰形式。
方式二:class类名控制
import './style.css'
function YourSelfComponent(){
return <div className='box'>div</div>
}
style.css文件:
.box{
color:#000;
}
注意:
-
react里不像原生里叫class属性,而是叫
className
-
对于多单词的css属性,style方式里需要写成小驼峰的形式
扩展
方式一也可以简单优化下:
const styles = {
color:'#000',
fontSize:'20px'
}
function YourSelfComponent(){
return <div style={styles}>div</div>
}
把样式写一个对象,抽出去存到变量里。dom身上看着轻量一些。