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)

相关推荐
阿里巴啦12 小时前
React + Three.js + R3F + Vite 实战:可交互的三维粒子化展厅
react.js·three.js·粒子化·drei·postprocessing·三维粒子化
[seven]13 小时前
React Router TypeScript 路由详解:嵌套路由与导航钩子进阶指南
前端·react.js·typescript
San3015 小时前
现代前端工程化实战:从 Vite 到 React Router demo的构建之旅
react.js·前端框架·vite
Qinana16 小时前
从零开始实现 GitHub 仓库导航器(Windows 实操版)
react.js·前端框架·vite
南山安16 小时前
React学习:Vite+React 基础架构分析
javascript·react.js·面试
一只叫煤球的猫17 小时前
我做了一个“慢慢来”的开源任务管理工具:蜗牛待办(React + Supabase + Tauri)
前端·react.js·程序员
前端无涯18 小时前
react组件(4)---高阶使用及闭坑指南
前端·react.js
AAA阿giao19 小时前
从零开始学 React:用搭积木的方式构建你的第一个网页!
前端·javascript·学习·react.js·前端框架·vite·jsx
赵财猫._.19 小时前
React Native鸿蒙开发实战(十):鸿蒙NEXT深度适配与未来展望
react native·react.js·harmonyos