React18学习笔记(六) React中的类组件,极简的状态管理工具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)

相关推荐
打小就很皮...5 小时前
ShowCountCard 功能迭代:新增周月对比属性,完善数据可视化场景
前端·react.js·信息可视化
HHHHHY5 小时前
使用阿里lowcode,手搓一个Carousel 走马灯容器组件
前端·react.js
小芒果nana6 小时前
React入门-JSX
react.js
Komorebi゛6 小时前
【React】配置别名路径
前端·react.js·前端框架
清羽_ls17 小时前
React Hooks 核心规则&自定义 Hooks
前端·react.js·hooks
mapbar_front1 天前
react项目开发—关于代码架构/规范探讨
前端·react.js
需要兼职养活自己1 天前
react高阶组件
前端·react.js
今天周二1 天前
vite 将react老项目中的没有兼容处理的写法转成兼容性写法
react.js
GISBox1 天前
GISBox如何让GeoTIFF突破Imagery Provider加载限制?
react.js·json·gis