文章目录
-
-
- 一.React中的类组件
- [二.zustand - 状态管理工具](#二.zustand - 状态管理工具)
- 三.React中的Typescript
-
一.React中的类组件
写在前面:
React的早期版本都是使用Class组件来编写代码的,因此类组件的学习仅限了解和为兼容老项目的场景做知识储备
1.什么是类组件?如何编写一个类组件
定义:通过JS中的类来组织组件的代码
步骤:
- 1.通过类属性
state
来定义状态数据 - 2.通过
setState
方法来修改状态数据 - 3.通过
render
来写UI模板(JSX语法)
示例:
javascript
//App.js
import { Component } from 'react'
class Counter extends Component {//基类:Component
//step1:定义状态变量
state={
count:0
}
//事件回调
clickHandler=()=>{
//step2:通过setState修改状态数据
this.setState({
count:this.state.count+1
})
}
//3.UI模板(JSX)
render(){
return <button onClick={this.clickHandler} >{this.state.count}</button>
}
}
*React18中可以把Counter作为子组件插入App中以显示效果
2.类组件的生命周期函数
定义:组件从创建到销毁的各个阶段自动执行的函数
常用且重要的2个生命周期函数:
1).componentDidMount
:组件挂载完毕时执行,使用场景:获取异步数据
2).componentWillUnmount
:组件卸载时自动执行,使用场景:清理副作用
示例:
javascript
//App.js
import { Component } from 'react'
class Counter extends Component {//基类:Component
//step1:定义状态变量
state={
count:0
}
//事件回调
clickHandler=()=>{
//step2:通过setState修改状态数据
this.setState({
count:this.state.count+1
})
}
/*生命周期*/
//组件渲染完毕时执行一次,发送网络请求
componentDidMount(){
console.log('组件渲染完毕了,发送网络请求...')
this.timer=setInterval(()=>{
console.log('定时器运行中...')
},1000)
}
//组件卸载时执行,清理副作用,如清除定时器,清除事件绑定
componentWillUnmount(){
console.log('组件卸载了,清除副作用...')
clearInterval(this.timer)
}
//3.UI模板(JSX)
render(){
return <button onClick={this.clickHandler} >{this.state.count}</button>
}
}
3.类组件的组件通信
概念:类组件和Hooks编写的组件,在组件通信的设计思路上完全一致
javascript
父传子:通过prop绑定数据
子传父:通过prop绑定父组件的函数,子组件调用
兄弟组件通信:状态提升
示例一:父传子:
javascript
//App.js
//父组件
class Parent extends Component{
render() {
return <Child msg="hello from Parent" />;
}
}
//子组件
class Child extends Component{
render() {
return <div>子组件接收到的数据:{this.props.msg}</div>;
}
}
示例二:子传父
javascript
//App.js
//父组件
class Parent extends Component{
render() {
const getSonMsg = (msg) => {
console.log('父组件收到子组件的消息:', msg)
}
return <div>
<div>父组件</div>
<Child onGetSonMsg={getSonMsg} />
</div>
}
}
//子组件
class Child extends Component{
render() {
const sendMsg = () => {
this.props.onGetSonMsg('hello from child')
}
return <div>
<div>子组件</div>
<button onClick={sendMsg}>点击子传父</button>
</div>
}
}
二.zustand - 状态管理工具
官网:https://awesomedevin.github.io/zustand-vue/docs/introduce/start/zustand
1.基础用法
流程:和redux一样:
- step1.创建store(新增状态数据和操作方法)
- step2. 绑定到组件
- step3.在组件中使用状态数据和方法
示例:
javascript
//创建store
const useStore=create((set)=>{
return{
//状态管理
count:1,
//修改状态变量的方法
inc:()=>{
set((state)=>({count:state.count+1}))
}
}
})
function App(){
//绑定store到组件
count {count,inc}=usStore()
return (
<button onClick={inc}>{count}</button>
)
}
export default App
2.异步写法
zustand
对异步的支持不需要特殊的操作,
直接在函数中书写异步逻辑,最后只需调用set方法并传入新状态即可
javascript
const useStore=create((set)=>{
return{
//状态管理
count:1,
channelList:[]
//修改状态变量的方法
inc:()=>{
set((state)=>({count:state.count+1}))
}
//异步方法
fetchChannelList:async ()=>{
const res=await fetch(URL)
const jsonData=await res.json()
//调用set方法更新状态变量
set({
channelList:jsonData.data.channels
})
}
}
})
function App(){
//绑定store到组件
count {count,inc}=useStore()
count {channelList,fetchChannelList}=useStore()
return (
<button onClick={inc}>{count}</button>
<ul>
{
channelList.map(item=><li key={item.id}>{item.name}</li>)
}
</ul>
)
}
3.切片模式
当单个store
比较大的时候,可以采用切片模式对模块进行拆分组合,类似于模块化
示例:把上例中的两个store
拆分成子模块
javascript
//App.js
import {create} from 'zustand'
//1.创建counter相关的切片
const createCounterStore=(set)=>{
return{
//状态管理
count:1,
//修改状态变量的方法
inc:()=>{
set((state)=>({count:state.count+1}))
}
}
}
const createChannelStore=(set)=>{
return{
//状态管理
count:1,
channelList:[]
//修改状态变量的方法
inc:()=>{
set((state)=>({count:state.count+1}))
}
//异步方法
fetchChannelList:async ()=>{
const res=await fetch(URL)
const jsonData=await res.json()
//调用set方法更新状态变量
set({
channelList:jsonData.data.channels
})
}
}
}
//3.组合切片
const useStore=create((...a)=>({
...createCounterStore,
...createChannelStore
}))
function App(){
//2.绑定store到组件
count {count,inc}=useStore()
count {channelList,fetchChannelList}=useStore()
return (
<button onClick={inc}>{count}</button>
<ul>
{
channelList.map(item=><li key={item.id}>{item.name}</li>)
}
</ul>
)
}
export default App
三.React中的Typescript
1.vite介绍
工程化工具:webpack,vite
官网:https://cn.vitejs.dev/guide/
vite是下一代的前端工具链,为开发提供极速响应
vite与框架无关,独立于框架,因此,基于vite可以创建与vue相关的项目,跟原生js的项目,或与react+ts相关的项目
2.创建项目
npm如何创建一个vite+react-ts
项目:
javascript
npm create vite@latest 项目名 -- template react-ts项目
(该命令同样可以用于创建vue,vue-ts,react项目)
- 1.安装
vite
并创建项目:npm create vite@latest my-react-ts-proj -- template react-ts
- 2.进入项目目录:
cd my-react-ts-proj
- 3.启动项目:
npm run dev
- 4.删除无关目录和文件:
javascript
目录:
assets
文件:
App.css
index.css
- 5.删除一些文件中的无关配置
javascript
//App.jsx
function App(){
return <>this is app </>
}
export default App
//main.js
//删掉index.css的引入
//严格节点会让代码执行两次,应该注释掉
//<React.StrictMode>
//<Provider store={store}><App /></Provider>
//</React.StrictMode>
//最终写法:
import ReactDom from 'react-dom/client'
import App from './App.tsx'
ReactDom.createRoot(document.getElementById('root')!).render(<App/>)
3.useState和TS
useState和TS有两种方式进行配合:
自动推导
通常react
会根据useState
的默认值来自动推导类型,不需要显式标注类型:const [toggle,setToggle]=useState(false)
传递泛型函数
useState
本身是一个泛型函数,可以传入具体类型的自定义类型
javascript
type User={
name:string,
age:number
}
const [user,setUser]=useState<User>()
什么时候把useState的初始值设置为null?
当不确定状态的初始值时,可以将其设置为null,此时类型要改成:const [user,setUser]=useState<User | null>(null)