2025年react组件constructor(react组件之间通信)

react组件constructor(react组件之间通信)JSX 是 js 和 html 的缩写 表示在 js 代码中编写 html 模板结构 JSX 可通过 识别 js 中的表达式 如变量 函数调用 方法等 注意 if 语句 switch 语句 变量声明属于语句 不是表达式 不能出现在 中 条件渲染

大家好,我是讯享网,很高兴认识大家。



JSX是js和html的缩写,表示在js代码中编写html模板结构
JSX可通过{}识别js中的表达式(如变量,函数调用,方法等)
注意:if语句,switch语句,变量声明属于语句,不是表达式,不能出现在{}中
​
条件渲染:可以通过逻辑与&&  三元表达式?:实现基础的条件渲染

讯享网

on+事件名称={事件处理程序} 整体上遵循驼峰命名法

使用事件对象参数


讯享网

传递自定义参数 (注意:不能直接写函数调用,这是事件绑定需要一个函数引用)

同时传递事件对象和自定义参数

在React中,一个组件就是首字母大写的函数,内部存放了组件的逻辑和视图UI,渲染组件只需要把组件当成标签书写

修改对象状态

对于对象类型的状态变量,传给set方法一个全新的对象来进行修改

父子通信

父传子

父组件传递数据 - 子组件标签上绑定属性

子组件接收数据 - 子组件通过props参数接收数据

子传父

在子组件中调用父组件的函数并传递参数

兄弟通信

状态提升实现兄弟组件通信

讯享网​ 

跨层通信

用于在React组件中创建不是由事件引起而是由渲染本身引起的操作(副作用),比如发送AJAX请求,更改DOM等等

自定义hook函数以use打头的函数

注意:

只能在组件中或者其它自定义Hook函数中调用

只能在组件的顶层调用,不能嵌套在if,for,其它函数中

export {increment,decrement} 供组件使用

export default counterReducer 共index.js整合

异步修改

默认二级路由设置 二级路由的path去掉,将index属性设为true

两种路由模式

讯享网1. 多处用到,封装token的存取删方法 setToken,getToken,removeToken在utils/token.js中 2. axios拦截,请求头中注入token 3. Axios拦截401状态码,清除失效token,跳转登录

项目打包:指将项目中的源代码和资源文件进行处理,生成 可在生成环境运行的静态文件的过程 npm run build ​ 本地预览(模拟服务器运行项目) 本地预览:指在本地通过静态服务器模拟生产服务器运行项目的过程 1.安装本地服务包 npm i -g serve 2.Serve -s https://blog.csdn.net/2301_/article/details/build 3.浏览器中访问 http://localhost:3000/

路由懒加载

  1. 把路由修改为由React提供的 lazy 函数进行动态导入
  2. 使用React内置的 Suspense组件 包裹路由中element选项对应的组件

包体积分析

讯享网通过可视化的方式,直观的体现项目中各种包打包之后的体积大小,方便做优化 ​ 
 
   
 
  1. 安装包 ​     source-map-explorer ​
  2. 配置命令指定要分析的js文件

CDN优化

CDN是一种内容分发网络服务,当用户请求网站内容时,由离用户最近的服务器将缓存的资源内容传递给用户     哪些资源可以放到CDN服务器? 体积较大的非业务JS文件, 比如react、react-dom 
 
   
 
  1. 体积较大,需要利用CDN文件在浏览器的缓存特性,加快加载时间
  2. 非业务JS文件,不需要经常做变动,CDN不用频繁更新缓存 ​ 项目中怎么做?
  • 把需要做CDN缓存的文件排除在打包之外(react、react-dom)
  • 以CDN的方式重新引入资源(react、react-dom)
  • useReducer
    讯享网和useState的作用类似,用来管理相对复杂的状态数据 ​ 基础用法 
     
       
     
    1. 定义一个reducer函数(根据不同的action返回不同的新状态)
    2. 在组件中调用useReducer,并传入reducer函数和状态的初始值
    3. 事件发生时,通过dispatch函数分派一个action对象(通知reducer要返回哪个新状态并渲染UI)

    useMemo
    作用:在组件每次重新渲染的时候缓存计算结果 原因:计算属性中,不是其依赖的值,发送变化时,计算属性也会进行再次计算(存在性能问题)

    memo
    讯享网作用:允许组件在Props没有改变的情况下跳过渲染 React组件默认的渲染机制:只要父组件重新渲染子组件就会重新渲染(如果子组件本身并不需要做渲染更新,存在浪费)

    // React.memo props比较机制 // 1. 传递一个简单类型的prop prop变化时组件重新渲染 // 2. 传递一个引用类型的prop 比较的是新值和旧值的引用是否相等 当父组件的函数重新执行时,实际上形成的是新的数组引用 // 3. 保证引用稳定 -> useMemo 组件渲染的过程中缓存一个值 import { memo, useMemo, useState } from ‘react’ const MemoSon = memo(function Son ({ list }) { console.log(‘子组件重新渲染了’) return <div>this is Son {list}</div> }) function App () { const [count, setCount] = useState(0) // const num = 100 const list = useMemo(() => { 
    讯享网return [1, 2, 3] 
    }, []) return (
    <div className="App"> <MemoSon list={list} /> <button onClick={() => setCount(count + 1)}>change Count</button> </div> 
    ) } export default App

    forwardRef

    讯享网// 子组件 const Son = forwardRef((props, ref) => { return <input type=“text” ref={ref} /> }) // 父组件 function App () { const sonRef = useRef(null) const showRef = () => { 
    console.log(sonRef) sonRef.current.focus() 
    } return (
    讯享网<> <Son ref={sonRef} /> <button onClick={showRef}>focus</button> </> 
    ) }
    useInperativeHandle

    通过ref暴露子组件中的方法

    // 子组件 const Son = forwardRef((props, ref) => { // 实现聚焦逻辑 const inputRef = useRef(null) const focusHandler = () => { 
    讯享网inputRef.current.focus() 
    } // 把聚焦方法暴露出去 useImperativeHandle(ref, () => {
    return { // 暴露的方法 focusHandler } 
    }) return <input type=“text” ref={inputRef} /> }) // 父组件 function App () { const sonRef = useRef(null) const focusHandler = () => {
    讯享网console.log(sonRef.current) sonRef.current.focusHandler() 
    } return (
    <> <Son ref={sonRef} /> <button onClick={focusHandler}>focus</button> </> 
    ) }

    讯享网// zustand 基础使用 import { create } from ‘zustand’ // 1. 创建store // 语法容易出错 // 1. 函数参数必须返回一个对象 对象内部编写状态数据和方法 // 2. set是用来修改数据的专门方法必须调用它来修改数据 // 语法1:参数是函数 需要用到老数据的场景
    // 语法2:参数直接是一个对象 set({ count: 100 })
    const useStore = create((set) => { return {
    // 状态数据 count: 0, // 修改状态数据的方法 inc: () => { set((state) => ({ count: state.count + 1 })) } 
    } }) // 2. 绑定store到组件 // useStore => { count, inc } function App () { const { count, inc } = useStore() return (
    讯享网<> <button onClick={inc}>{count}</button> </> 
    ) } export default App
    // zustand 切片模式 import { useEffect } from ‘react’ import { create } from ‘zustand’ const URL = ‘http://geek.itheima.net/v1_0/channels' // store // counterStore
    // channelStore // index.js
    // 1. 拆分子模块 再组合起来 const createCounterStore = (set) => { return {
    讯享网// 状态数据 count: 0, // 修改状态数据的方法 inc: () => { set((state) => ({ count: state.count + 1 })) }, 
    } } const createChannelStore = (set) => { return {
    channelList: [], fetchGetList: async () => { const res = await fetch(URL) const jsonRes = await res.json() set({ channelList: jsonRes.data.channels }) } 
    } } const useStore = create((…a) => { return {
    讯享网...createCounterStore(...a), ...createChannelStore(...a) 
    } }) function App () { // 2. 组件使用 const { count, inc, fetchGetList, channelList } = useStore() useEffect(() => {
    fetchGetList() 
    }, [fetchGetList]) return (
    讯享网<> <button onClick={inc}>{count}</button> <ul> { channelList.map(item => <li key={item.id}>{item.name}</li>) } </ul> </> 
    ) } export default App
    // zustand 异步支持 import { useEffect } from ’react‘ import { create } from ’zustand‘ const URL = ’http://geek.itheima.net/v1_0/channels' // 1. 创建store // 语法容易出错 // 1. 函数参数必须返回一个对象 对象内部编写状态数据和方法 // 2. set是用来修改数据的专门方法必须调用它来修改数据 // 语法1:参数是函数 需要用到老数据的场景
    // 语法2:参数直接是一个对象 set({ count: 100 })
    const useStore = create((set) => { return {
    讯享网// 状态数据 count: 0, // 修改状态数据的方法 inc: () => { set((state) => ({ count: state.count + 1 })) }, channelList: [], fetchGetList: async () => { const res = await fetch(URL) const jsonRes = await res.json() set({ channelList: jsonRes.data.channels }) } 
    } }) // 2. 绑定store到组件 // useStore => { count, inc } function App () { const { count, inc, fetchGetList, channelList } = useStore() useEffect(() => {
    fetchGetList() 
    }, [fetchGetList]) return (
    讯享网<> <button onClick={inc}>{count}</button> <ul> { channelList.map(item => <li key={item.id}>{item.name}</li>) } </ul> </> 
    ) } export default App

    基于vite创建开发环境

    npm create vite@latest react-ts-pro – –template react-ts

    npm create vite@latest 固定写法 (使用最新版本vite初始化项目)

    react-ts-pro 项目名称 (可以自定义)

    – –template react-ts 指定项目模版位react+ts

    useState与TS
    useState - 自动推导 (会根据传入useState的默认值自动推导类型,不需要显示标注类型) const [value,toggle] = useState(false) 
     
       
     
    1. value: 类型为boolean
    2. toggle: 参数类型为boolean
    讯享网useState - 传递泛型参数 (useState本身是一个泛型函数,可以传入具体的自定义类型) type User = { name:string, age:number } const [user,setUser] = useState<User>() 
  • 限制useState函数参数的初始值必须满足类型为: User | ()=> User
  • 限制setUser函数的参数必须满足类型为:User | ()=> User | undefined
  • user状态数据具备User类型相关的类型提示
  • useState - 初始值为null 当我们不知道状态的初始值是什么,将useState的初始值为null是一个常见的做法,可以通过具体类型联合null来做显式注解 type User = { name:string, age:number } const [user,setUser] = useState<User | null>(null) 
  • 限制useState函数参数的初始值可以是 User | null
  • 限制setUser函数的参数类型可以是 User | null
  • 事件与TS
    讯享网为事件回调添加类型 为事件回调添加类型约束需要使用React内置的泛型函数来做,比如最常见的鼠标点击事件和表单输入事件

    通过泛型函数约束了整个事件回调函数的类型,主要是为了约束事件参数e的类型

    props与TS
    为组件prop添加类型,本质是给函数的参数做类型注解,可以使用type对象类型或者interface接口来做注解 type Props = { className:string } function Button(props:Props){ const {className} = props return <button className={className}></button> } 说明:Button组件只能传入名称为className的prop参数,类型为string, 且为必填
    讯享网 为children添加类型 children是一个比较特殊的prop, 支持多种不同类型数据的传入,需要通过一个内置的ReactNode类型来做注解 type Props = { className:string, children:React.ReactNode } function Button(props:Props){ const {className,children} = props return <button className={className}>{children}</button> } 说明:注解之后,children可以是多种类型,包括:React.ReactElement 、string、number、 React.ReactFragment 、React.ReactPortal 、boolean、 null 、undefined
    为事件prop添加类型 组件经常执行类型为函数的prop实现子传父,这类prop重点在于函数参数类型的注解 type Props = { onGetMsg?:(msg:string)=>void } function Son(props:Props){ const {onGetMsg} = props const clickHandler = ()=>{ onGetMsg?.(‘this is msg’) } return <button onClick={clickHandler}>sendMsg</button> } 父组件 return( 
    讯享网<> <Son onGetMsg={(msg)=>console.log(msg)} /> </> 
    ) 父组件 const getMsgHandler = (msg:string)=>{
    console.log(msg) 
    } return( <>
    讯享网<Son onGetMsg={getMsgHandler}/> 
    </> ) 说明:
    1. 在组件内部调用时需要遵守类型的约束,参数传递需要满足要求
    2. 绑定prop时如果绑定内联函数直接可以推断出参数类型,否则需要单独注解匹配的参数类型
    useRef与TS
    获取dom 获取dom的场景,可以直接把要获取的dom元素的类型当成泛型参数传递给useRef,可以推导出.current属性的类型 function App(){ const domRef = useRef<HTMLInputElement>(null) useEffect(()=>{ domRef.current?.focus() },[]) return( <> <input ref={domRef}/> </> ) }
    讯享网引用稳定的存储器 把useRef当成引用稳定的存储器使用的场景可以通过泛型传入联合类型来做,比如定时器的场景 function App(){ const timerRef = useRef<number | undefined>(undefined) useEffect(()=>{ timerRef.current = setInterval(()=>{ console.log(‘1’) },1000) return ()=> clearInterval(timerRef.current) },[]) return <>this is div</> }

    小讯
    上一篇 2025-05-15 07:02
    下一篇 2025-05-17 13:07

    相关推荐

    版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
    如需转载请保留出处:https://51itzy.com/kjqy/186440.html