欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 名人名企 > react+typescript+vite+tailwind css学习总结(react19最新版)持续更新

react+typescript+vite+tailwind css学习总结(react19最新版)持续更新

2025/2/12 13:25:39 来源:https://blog.csdn.net/qq_58055766/article/details/145275818  浏览:    关键词:react+typescript+vite+tailwind css学习总结(react19最新版)持续更新

一、新建项目 

通过以下代码构建全新react+vite项目:

npm create vite@latest my-react-app -- --template react-ts

新建完后将react与react-dom改为19.0.0 

 

执行以下代码加载包:

npm install

二、配置项目 

1.eslint+prettier

参考vscode——Prettier插件保存自动格式化-腾讯云开发者社区-腾讯云

默认vite安装后都有eslint,然后开启eslint和prettier插件,然后在设置里edit format选prettier

新增

    "format": "prettier --write \"src/**/*.+(js|ts|jsx|tsx)\""

package.json如下 

{"name": "flinkopsui","private": true,"version": "0.0.0","type": "module","scripts": {"dev": "vite","build": "tsc -b && vite build","lint": "eslint .","preview": "vite preview","format": "prettier --write \"src/**/*.+(js|ts|jsx|tsx)\""},"dependencies": {"flinkopsui": "file:","prettier": "^3.4.2","react": "^19.0.0","react-dom": "^19.0.0"},"devDependencies": {"@eslint/js": "^9.19.0","@types/react": "^19.0.8","@types/react-dom": "^19.0.3","@vitejs/plugin-react": "^4.3.4","eslint": "^9.19.0","eslint-config-prettier": "^10.0.1","eslint-plugin-prettier": "^5.2.3","eslint-plugin-react-hooks": "^5.0.0","eslint-plugin-react-refresh": "^0.4.18","globals": "^15.14.0","typescript": "~5.7.2","typescript-eslint": "^8.22.0","vite": "^6.1.0"}
}

然后在根目录新建cjs文件配置prettier

module.exports = {// 箭头函数只有一个参数时,可以省略参数的括号arrowParens: "avoid",// 对象字面量中括号与内部内容之间不加空格bracketSpacing: true,// 使用 Unix 格式的行结束符 (\n)endOfLine: "lf",// 每行的最大长度限制为 100 个字符printWidth: 100,// Markdown 文件中的文本是否换行,`preserve` 表示保持现状proseWrap: "preserve",// 在语句末尾添加分号semi: false,// 使用双引号而不是单引号singleQuote: false,// 缩进时每级使用 2 个空格tabWidth: 2,// 使用空格而不是制表符进行缩进useTabs: false,// 在多行对象或数组的最后一项后添加逗号(es5 支持的范围内)trailingComma: "es5",// 解析器设置为 TypeScriptparser: "typescript",plugins: ["prettier-plugin-tailwindcss"],
};

如果一直报错执行底下: 

mv .prettierrc.js .prettierrc.cjs

设置完记得重启vscode 

2.tailwind css

vite安装:参考Install Tailwind CSS with Vite - Tailwind CSS

3.ant design

三、react与JavaScript与JSX基础知识

1.标签

1.html标签必须闭合。

2.JSX片段必须首字母大写。

3.每段JSX只能有一个根节点,也就是必须有且要有一个<div></div>进行包裹。

3.Fragment:通过<></>可以不声明最外层div,避免块级元素重复使用。

2.属性

1.定义样式的class需要改为className。

2.style要使用JS对象,不能直接采用string形式,并且key要用驼峰命名法。

3.for要改为htmlFor。

3.事件

1.JSX监听事件分为点击事件、鼠标事件等等监听,onClick,采用onXXX的形式。

2.必须传入一个函数(还须注意在JSX里引用JSX需要{})=>形式为fn而不是fn(),若使用fn()则表示直接调用此函数,我们采用fn的形式类似于挂载。

3.传参如下:声明类型、在JSX中使用箭头函数进行传参,在(event)可以理解为 事件发生时,浏览器自动创建并传递的一个 事件对象,然后传递给方法。

import type {MouseEvent} from "react";const fn = (event: MouseEvent<HTMLButtonElement>)=>{event.preventDefault();console.log("123")
}<button onClick={(event) => fn(event)}>Click me</button>

4.JS变量或表达式

1.通过{/* */}在JSX中写注释。

2.通过{***}可以插入JS变量、函数、表达式。

5.条件判断

条件判断有三种:

1.通过&&进行判断=>适用于数据隐藏、显示。

2.三元表达式进行判断=>适用于数据切换显示。

3.函数进行判断=>通过显示函数的方式进行判断(注意:首字母要大写,函数与html都要大写)。

 function HelloIf(){if(flag) return "hello"return "helloelse"
}{flag && <p>123456</p>}{flag ? <p>123</p> : <p>321</p>}<HelloIf></HelloIf>

6.循环 

在JSX中使用map进行循环,并且要指定key,key必须是唯一的。

示例代码解释:首先新建list数组、通过map进行遍历,user为每一个遍历出来的元素,通过箭头函数进行返回,将其解构为username、name,key必须采用{}这样才使用的是对象而不是静态字符串。

注:在JSX里只要使用JavaScript就得先提前加上{}。 

const list = [{username:"1",name:"123"},{username:"2",name:321}
]<ul>{list.map(user=>{const {username,name} = userreturn <li key={username}>{name}</li>})}</ul>

四、react传参

五、react hooks

1.useState

useState当JSX中未使用的时候则不需要用useState,因为组件是个函数,并且useState会触发组件的更新,替代方法为useRef,并且useState为异步更新,也就是无法在JS中拿到最新的值(因为其实自己已经知道这个值)。

使用函数可以防止异步更新不合并。 

 1.2 useState值不可变 

 useState的值为不可变,也就是不能直接修改里面的值,要通过传入新的值的方式,通过新值或函数返回新值的方式更新,可以使用解构语法简化。

 数组改变方式,用concat不能用push,因为concat返回一个数组新值。

1.3useState使用情况 

所有组件的定义一定要首字母大写,要不然useState会报错。 

1.4useState改变方法 

1.4.1原始修改方法

增:concat

  function add() {// setCount(count + 1)const r = Math.random().toString().slice(-3);setQuestionList(// 新增 concatquestionList.concat({id: "q" + r,title: "问卷" + r,isPublished: false,}));}

删:fitter

  function deleteQuestion(id: string) {// // 不可变数据setQuestionList(// 删除 filterquestionList.filter(q => {if (q.id === id) return false;else return true;}));}

改:map 

  function publishQuestion(id: string) {setQuestionList(// 修改 mapquestionList.map(q => {if (q.id !== id) return q;return {...q,isPublished: true,};}));}
1.4.2 immer修改方法
  function add() {// setCount(count + 1)const r = Math.random().toString().slice(-3);// setQuestionList(//   // 新增 concat//   questionList.concat({//     id: "q" + r,//     title: "问卷" + r,//     isPublished: false,//   })// );// immer 的方式setQuestionList(produce(draft => {draft.push({id: "q" + r,title: "问卷" + r,isPublished: false,});}));}function deleteQuestion(id: string) {// // 不可变数据// immer 的方式setQuestionList(produce(draft => {const index = draft.findIndex(q => q.id === id);draft.splice(index, 1);}));}function publishQuestion(id: string) {// immer 的方式setQuestionList(produce(draft => {const q = draft.find(item => item.id === id);if (q) q.isPublished = true;}));}

2.useEffect 

可以理解为监听,组件销毁时,组件特定值变化时([]里进行填写)

  useEffect(() => {console.log("Component mounted");return () => {console.log("Component unmounted");};}, []); // 空依赖数组,表示仅在组件挂载和卸载时触发

 3.useRef

跟Vue3的ref不同,Vue3的ref是操作响应式数据,而react的useRef是操作dom节点的。

去保存一个值,不影响页面显示,用useRef,因为useRef不会导致rerender,也就是页面更新,如果需要改变页面,则用useState。

import { useRef } from "react";const RefTest = () => {const select = useRef<HTMLInputElement>(null);function changeSelect() {const inputElem = select.current;if (inputElem) inputElem.select();}return (<div><input ref={select} defaultValue={"Hello world"}></input><button onClick={changeSelect}>改变数据</button></div>);
};export default RefTest;

4.useMemo

5.useCallback

6.自定义hook 

首先自定义hook需要以use开头。

第一步:在src目录下新建hooks文件夹,并创建以use开头的hook的ts文件,由于没有使用JSX语法,所以只需要ts文件即可。

第二步:声明函数,并记得处理销毁事件,防止内存泄漏。

import { useEffect, useState } from "react"const useHooktest = () => {const [x, setX] = useState(0)const [y, setY] = useState(0)const mouseMoveHandler=(event: MouseEvent) => {setX(event.clientX)setY(event.clientY)}useEffect(() => {window.addEventListener('mousemove', mouseMoveHandler);return () => {window.removeEventListener('mousemove',mouseMoveHandler)}}, [])return {x,y}
}export default useHooktest

 在父组件进行引用并结构,即可正常使用自定义hook。

// import List2 from "./list2";
// import RefTest from "./components/useRefTest";
import useHooktest from "./hooks/useHooktest";function App() {const { x, y } = useHooktest();return (<div><p>{x}</p><p>{y}</p></div>);
}export default App;

 7.hooks对比参考:​​​​​​

https://medium.com/@ksshravan667/14-days-of-react-day-5-react-hooks-usestate-useref-useeffect-usememo-usecallback-8599a14c4e2b 

8.Hooks使用规则

 七、CSS

1.使用css module解决相同命名

解决问题:比如一个页面引用多个组件,那么各个组件调用的css有相同命名的,通过以下方法解决。

vite自带css module,所以在创建文件的时候采用,xxx.module.css

引用的时候使用styles

import styles from "./questionCard.module.css";<div className={styles["list-item"]}>123</div>

css module会自行给class进行命名 

2.避免使用内联样式,并且通过使用classnames或clsx代替if else进行样式判断

3.采用sass

使用sass进行编写可以直接嵌套

npm install sass

 八、正式开始实战

1.新建pages页面、components组件

2.路由

2.1安装

npm install react-router-dom

3.outlet

react实现固定区域与变化区域,通过outlet实现变化区域,就比如管理员需要固定的侧边栏进行导航,然后通过outlet进行对应渲染。

个人理解:

就是首先我有个底层的父路由,就比如有个/对应的MainLayout,那么它是顶层渲染,然后子组件是否是必须设置为它的children,然后react就是通过outlet去通过不同路由定位显示不同的子组件,然后vue就是通过router-view去定位显示不同的子组件,您看我这个理解对不对

第一步创建路由配置

import { createBrowserRouter } from 'react-router-dom'
import MainLayout from '../layouts/MainLayout'
import Login from '../pages/Login'
import Home from '../pages/Home'
import NotFound from '../pages/404NotFound'const router = createBrowserRouter([{path: 'login',element: <Login />,},{path: '/',element: <MainLayout />,children: [{path: 'home',element: <Home />,},],},//*的意思是以上都不匹配执行 404 Not Found写在最后{path: '*',element: <NotFound />,},
])export default router

第二步在app.tsx中引用

import { RouterProvider } from 'react-router-dom'
import routerConfig from './router'
function App() {return <RouterProvider router={routerConfig}></RouterProvider>
}export default App

3.渲染底层知识 

4.路由导航

4.1useNavigate钩子

采用react router的useNavigate钩子进行导航

示例如下:

import { useNavigate } from 'react-router-dom';const ViewsPage = () => {const navigate = useNavigate();const goToTest1 = () => {navigate('/views/test1'); // 导航到 /views/test1 路由};return (<div><button onClick={goToTest1}>Go to Test1</button></div>);
};export default ViewsPage;

 4.2Link组件

import { Outlet, Link } from 'react-router-dom';const MainLayout = () => {return (<div><header><nav><Link to="/home">Home</Link><Link to="/about">About</Link></nav></header><aside>固定的侧边栏</aside><main><Outlet /> {/* 动态内容 */}</main></div>);
}export default MainLayout;

4.3传递参数

4.4接收参数

采用useParams钩子进行参数的接收

 采用useSearchParams钩子进行参数搜索

5.自定义标题与icon

全局在index.html中进行修改

单独修改使用ahooks(但是目前貌似还不支持react19)

第一步:

npm install --save ahooks

九、细节理解 

1.React.FC声明与传参理解

1.1Vue3与React19传递参数对比

父组件向子组件传递参数 

 子组件向父组件传递参数 

子组件互相传递参数 

 1.2React.FC理解

版权声明:

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

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