欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > 【React+ts】 react项目中引入bootstrap、ts中的接口

【React+ts】 react项目中引入bootstrap、ts中的接口

2025/1/27 13:46:21 来源:https://blog.csdn.net/weixin_43872912/article/details/145366886  浏览:    关键词:【React+ts】 react项目中引入bootstrap、ts中的接口

一、在react项目中引入bootstrap

这个直接用npm下载包然后在index.js中引入就可以了。

npm install bootstrap react-bootstrap

后面那个必须要下载,应该有什么联动的包要用。
然后在index.tsx中引入

import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap/dist/js/bootstrap";

二、ts中的interface接口

2.1 对象类型接口

ts中的interface是用来描述对象或函数的。是一种代码协作必须遵守的契约。我的理解就是规范里面的数据,比如说,在实例化的时候哪些东西必须要,哪些东西可以不要,以及哪些东西可以任意类型。
里面的数据可以定义以下几种类型。

  1. 确定类型:必须要有的数据。
  2. 可选属性:可以没有的属性。
  3. 任意属性:说明属性类型可以更改,名字可定义。
  4. 只读属性:实例化后不可更改。
interface Person {age: number,           // 确定属性name?: string,         // 可选属性(加问号即可)[propName: string]: any, // 任意属性readonly sex: string,  // 只读属性
}

2.2 函数类型接口

列出参数列表和返回值类型的定义。

// 函数类型接口
interface Func {// 定义接收两个必选 number 类型参数,和一个可选字符串参数 desc,该函数返回 number 类型(x: number, y: number, desc?: string): number
}

三、react中定义组件的方式

有两种定义组件方式,一种是函数式组件,一种是类式组件。

3.1函数式组件

//基本定义方式
import React from "react";export default function Discovery() {return <div>发现页</div>;
}//组件传参数
import React from "react";export default function Discovery(props: any) {console.log(props);return <div>{props.text}</div>;
}//类型定义,说明是个函数式组件也可以简写FC
import React, { memo } from "react”;
Import type {FunctionComponent} from "react”;const Discovery: FunctionComponent<any> = (props) => {console.log(props);return <div>{props.text}</div>;
};//memo函数的作用是判断组件是否发生变化,如果没有发生变化则不重新渲染
export default memo(Discovery);

3.2 类式组件

//基本定义方式
import React, { Component } from "react";class Discovery extends Component {render() {return <div>发现页</div>;}
}export default Discovery;//类式组件传参
import React, { Component } from "react”;
//这里两个any定义的一个是props type,一个是state typeclass Discovery extends Component<any, any> {  constructor(props: any) {super(props);console.log(props);this.state = { text: props.text };}render() {return <div>{this.props.text}</div>;}
}
export default Discovery;

3.3interface与类式组件的互动

ReactNode和ReactElement 与 children属性
这里的ReactNode包含了ReactElement,如下图所示。
在这里插入图片描述
InterfaceTest.tsx

import React, { ReactNode } from "react";interface Iprops {name: string;age: number;children: ReactNode;height?: number;
}export default function InterfaceTest(props: Iprops) {return (<div><div>name:{props.name}</div><div>age:{props.age}</div>{/* 三目运算符来条件渲染 */}{props.height ? <div>height:{props.height}</div> : null}<div>{props.children}</div></div>);
}

Discovery.tsx

import React, { Component } from "react";
import InterfaceTest from "./InterfaceTest";
class Discovery extends Component<any, any> {constructor(props: any) {super(props);console.log(props);this.state = { text: props.text };}render() {return (<div>{this.props.text}<InterfaceTest name="Carling" age={21} height={187}><div>这里是子元素</div></InterfaceTest></div>);}
}export default Discovery;

在这里插入图片描述

3.4代码中遇到的问题

(1)如果是类组件,子组件是否重新渲染由props和state决定;如果子组件是函数式组件,那么只要父组件渲染,子组件就会无条件进行渲染。
answer:使用memo函数对组件进行包裹。这个方法只能解决子组件属性不是函数时的情况,如果子组件是函数,则需要使用useCallback进行包裹。

这个问题出现的原因是因为,函数式组件每次重新渲染时,都会把函数体里的所有代码执行一遍。
useCallback函数

let newFunction = useCallback(oldFunction,[dependentValue])

我的理解是只有当后面的依赖值发生变化时,前面的函数才会被运行。否则返回一样的值。
因此如果传的是空数组则oldFunction只会被定义一次。

export default () => {console.log("父组件");const [count, setCount] = useState(1);let changeCount = () => {setCount(count + 1);}let increment = useCallback(()=>{console.log("increment");},[]) // 该函数永远不会重新定义(没有依赖)return (<><h1>useCallback</h1><p>{count}</p><input type="button" value="修改count" onClick={changeCount} /><hr/><SonFn onMyClick={increment} /></>)
}

四、组件的懒加载–webpack中的分包处理,性能优化问题–哪个需要查看下载哪个。

这个的原理就是将所有组件拆分,不放在一个文件里,哪个需要被加载去服务器下载哪个文件。
这里使用的是react库中的lazy函数,用来引入组件。
路由表定义:

import React, { lazy } from "react";
import { Navigate } from "react-router-dom";//懒加载定义
const Discovery = lazy(() => import("../components/Discovery"));
const My = lazy(() => import("../components/My"));
const Follow = lazy(() => import("../components/Follow"));
const Mall = lazy(() => import("../components/Mall"));
const Musician = lazy(() => import("../components/Musician"));
const Recommended = lazy(() => import("../components/Recommended"));
const Download = lazy(() => import("../components/Download"));const routes: any[] = [{path: "/discovery",element: <Discovery text="发现页" />,},{path: "/my",element: <My />,},{path: "follow",element: <Follow />,},{path: "mall",element: <Mall />,},{path: "musician",element: <Musician />,},{path: "recommended",element: <Recommended />,},{path: "download",element: <Download />,},{path: "/",element: <Navigate to="/discovery" />,},
];
export default routes;

使用路由表的时候要用Suspense组件进行包裹,Suspense组件是通过捕获异常来进行实现的,没看之前猜测是,捕获到异常就暂停该组件的渲染,等到完成再渲染。
工作原理:
使用React的Fiber架构进行实现。Fiber架构允许React将渲染工作拆分为一个个可中断的任务单元。当遇到需要暂停的操作时,Fiber可暂停当前任务,并显示fallback—Suspense组件中定义的在等待时渲染的过渡组件。

  1. 当组件抛出异常时,React标记该Fiber节点为“suspended”状态
  2. 触发重新渲染,一旦该Promise完成,React会尝试重新渲染组件。
  3. 等待Promise完成的期间会渲染fallback。
    用Suspense组件将所有懒加载的组件全包裹了就可以。
import React, { Suspense } from "react";
import routes from "./router/index";
import { NavLink, useRoutes } from "react-router-dom";function App() {const element = useRoutes(routes);return (<div className="App"><nav className="navbar navbar-dark bg-primary"><div className="container-fluid"><NavLink className="navbar-brand" to="/discovery">发现音乐</NavLink><NavLink className="navbar-brand" to="/my">我的音乐</NavLink><NavLink className="navbar-brand" to="/follow">关注</NavLink><NavLink className="navbar-brand" to="/mall">商城</NavLink><NavLink className="navbar-brand" to="/musician">音乐人</NavLink><NavLink className="navbar-brand" to="/recommended">云推歌</NavLink><NavLink className="navbar-brand" to="/download">下载客户端</NavLink></div></nav><Suspense fallback="loading…">{element}</Suspense></div>);
}export default App;

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com