2026/1/9 4:13:25
网站建设
项目流程
网站开发尺寸,铜煤建设网站,旅游网站建设标书,传奇4端游⚛️ React Hooks TypeScript完全指南#xff1a;从入门到精通#x1f4a1; 核心提示#xff1a;React Hooks结合TypeScript为现代前端开发提供了类型安全的函数式编程体验。本文深入解析所有内置Hooks、自定义Hooks开发、性能优化技巧#xff0c;助您掌握React Hooks的精髓…⚛️ React Hooks TypeScript完全指南从入门到精通 核心提示React Hooks结合TypeScript为现代前端开发提供了类型安全的函数式编程体验。本文深入解析所有内置Hooks、自定义Hooks开发、性能优化技巧助您掌握React Hooks的精髓。在React 18.0和TypeScript 5.0的技术背景下Hooks已成为现代React开发的核心范式。它不仅彻底改变了组件的编写方式更为开发者带来了函数式编程的优雅体验。结合TypeScript的强类型系统我们能够构建更加健壮、可维护的应用程序。 技术背景与发展历程timeline title React Hooks 发展历程 section 2018 React Hooks 1.0发布 : 函数组件革命 section 2019 TypeScript集成完善 : 类型安全支持 section 2020 自定义Hooks普及 : 社区生态繁荣 section 2021 性能优化成熟 : 最佳实践确立 section 2022-2023 React 18 并发特性 : 现代化演进 本文核心价值⚛️ 全面覆盖从基础到高级涵盖所有内置Hooks 实战导向10生产级自定义Hooks和实战案例⚡ 性能优化深入的调优技巧和性能分析 最佳实践企业级开发规范和架构模式 前沿技术React 18新特性和未来趋势 React Hooks基础概念 Hooks核心原理函数组件React Hooks状态管理副作用处理性能优化上下文访问useStateuseReduceruseEffectuseLayoutEffectuseMemouseCallbackReact.memouseContextuseRef Hooks使用规则规则类型具体要求⚡违反后果正确做法 调用位置只能在函数组件或自定义Hooks中调用❌ Hook规则错误✅ 在React函数体内调用 调用顺序每次渲染必须按相同顺序调用❌ 状态混乱✅ 条件语句放在Hook内部⚡ 命名规范自定义Hook必须以’use’开头❌ Hook检测失败✅ 遵循命名约定⚛️ 内置Hooks完全指南1️⃣ useState Hook状态管理基础// 基础用法importReact,{useState}fromreact;interfaceUserProfile{name:string;age:number;email:string;}constUserProfileComponent:React.FC(){// 字符串状态const[name,setName]useStatestring(John Doe);// 数字状态const[age,setAge]useStatenumber(25);// 对象状态const[profile,setProfile]useStateUserProfile({name:John Doe,age:25,email:johnexample.com});// ️ 函数式更新constincrementAge(){setAge(prevAgeprevAge1);// 类型安全的函数式更新};// 部分对象更新constupdateProfile(updates:PartialUserProfile){setProfile(prev({...prev,...updates}));};return(divh2用户信息/h2p姓名:{name}/pp年龄:{age}/pbutton onClick{incrementAge}年龄1/button/div);};2️⃣ useEffect Hook副作用处理importReact,{useEffect,useState}fromreact;// 数据获取示例interfacePost{id:number;title:string;body:string;}constDataFetcher:React.FC(){const[posts,setPosts]useStatePost[]([]);const[loading,setLoading]useStateboolean(true);const[error,setError]useStatestring|null(null);// 数据获取EffectuseEffect((){constfetchPostsasync(){try{setLoading(true);constresponseawaitfetch(https://api.example.com/posts);constdata:Post[]awaitresponse.json();setPosts(data);setError(null);}catch(err){setError(errinstanceofError?err.message:未知错误);}finally{setLoading(false);}};fetchPosts();},[]);// 空依赖数组只在组件挂载时执行// ️ 浏览器API订阅useEffect((){consthandleResize(){console.log(窗口大小改变:,window.innerWidth);};window.addEventListener(resize,handleResize);// 清理函数组件卸载时执行return(){window.removeEventListener(resize,handleResize);};},[]);// ⏰ 定时器示例useEffect((){consttimersetInterval((){console.log(定时器执行);},1000);return()clearInterval(timer);},[]);if(loading)returndiv加载中.../div;if(error)returndiv错误:{error}/div;return(divh2文章列表/h2{posts.map(post(div key{post.id}h3{post.title}/h3p{post.body}/p/div))}/div);};3️⃣ useContext Hook上下文访问importReact,{createContext,useContext,useState,ReactNode}fromreact;// ️ 创建Context类型定义interfaceThemeContextType{theme:light|dark;toggleTheme:()void;colors:{background:string;text:string;primary:string;};}// 创建ContextconstThemeContextcreateContextThemeContextType|undefined(undefined);// ️ Provider组件interfaceThemeProviderProps{children:ReactNode;}constThemeProvider:React.FCThemeProviderProps({children}){const[theme,setTheme]useStatelight|dark(light);constcolors{light:{background:#ffffff,text:#000000,primary:#007bff},dark:{background:#1a1a1a,text:#ffffff,primary:#4dabf7}};consttoggleTheme(){setTheme(prevprevlight?dark:light);};constvalue:ThemeContextType{theme,toggleTheme,colors:colors[theme]};return(ThemeContext.Provider value{value}{children}/ThemeContext.Provider);};// 自定义Hook安全访问ContextconstuseTheme():ThemeContextType{constcontextuseContext(ThemeContext);if(contextundefined){thrownewError(useTheme must be used within a ThemeProvider);}returncontext;};// 使用示例constThemedComponent:React.FC(){const{theme,toggleTheme,colors}useTheme();return(div style{{backgroundColor:colors.background,color:colors.text,padding:20px,borderRadius:8px}}h2当前主题:{theme}/h2button onClick{toggleTheme}style{{backgroundColor:colors.primary}}切换主题/button/div);};4️⃣ useReducer Hook复杂状态管理importReact,{useReducer,Reducer}fromreact;// 状态类型定义interfaceTodo{id:number;text:string;completed:boolean;createdAt:Date;}interfaceTodoState{todos:Todo[];filter:all|active|completed;nextId:number;}// Action类型定义typeTodoAction|{type:ADD_TODO;text:string}|{type:TOGGLE_TODO;id:number}|{type:DELETE_TODO;id:number}|{type:SET_FILTER;filter:all|active|completed}|{type:CLEAR_COMPLETED};// ️ Reducer函数consttodoReducer:ReducerTodoState,TodoAction(state,action){switch(action.type){caseADD_TODO:return{...state,todos:[...state.todos,{id:state.nextId,text:action.text,completed:false,createdAt:newDate()}],nextId:state.nextId1};caseTOGGLE_TODO:return{...state,todos:state.todos.map(todotodo.idaction.id?{...todo,completed:!todo.completed}:todo)};caseDELETE_TODO:return{...state,todos:state.todos.filter(todotodo.id!action.id)};caseSET_FILTER:return{...state,filter:action.filter};caseCLEAR_COMPLETED:return{...state,todos:state.todos.filter(todo!todo.completed)};default:// 类型安全确保处理所有action类型const_exhaustiveCheck:neveraction;returnstate;}};// ️ Todo组件constTodoApp:React.FC(){const[state,dispatch]useReducer(todoReducer,{todos:[],filter:all,nextId:1});const[inputText,setInputText]useState();consthandleAddTodo(){if(inputText.trim()){dispatch({type:ADD_TODO,text:inputText});setInputText();}};// 过滤todosconstfilteredTodosstate.todos.filter(todo{switch(state.filter){caseactive:return!todo.completed;casecompleted:returntodo.completed;default:returntrue;}});return(divh1Todo应用/h1divinputtypetextvalue{inputText}onChange{(e)setInputText(e.target.value)}onKeyPress{(e)e.keyEnterhandleAddTodo()}/button onClick{handleAddTodo}添加/button/divdivbutton onClick{()dispatch({type:SET_FILTER,filter:all})}全部/buttonbutton onClick{()dispatch({type:SET_FILTER,filter:active})}活跃/buttonbutton onClick{()dispatch({type:SET_FILTER,filter:completed})}已完成/button/divul{filteredTodos.map(todo(li key{todo.id}inputtypecheckboxchecked{todo.completed}onChange{()dispatch({type:TOGGLE_TODO,id:todo.id})}/span style{{textDecoration:todo.completed?line-through:none}}{todo.text}/spanbutton onClick{()dispatch({type:DELETE_TODO,id:todo.id})}删除/button/li))}/ulbutton onClick{()dispatch({type:CLEAR_COMPLETED})}清除已完成/button/div);};5️⃣ useMemo useCallback性能优化importReact,{useState,useMemo,useCallback}fromreact;// 数据类型定义interfaceProduct{id:number;name:string;price:number;category:string;rating:number;}interfaceFilterOptions{category:string;minPrice:number;maxPrice:number;searchQuery:string;}// ️ 产品列表组件constProductList:React.FC{products:Product[]}React.memo(({products}){console.log(ProductList 重新渲染);return(ul{products.map(product(li key{product.id}h4{product.name}/h4p价格:¥{product.price}/pp评分:{⭐.repeat(Math.round(product.rating))}/p/li))}/ul);});constProductApp:React.FC(){const[products]useStateProduct[]([{id:1,name:iPhone,price:9999,category:手机,rating:4.5},{id:2,name:MacBook,price:12999,category:电脑,rating:4.8},{id:3,name:AirPods,price:1299,category:耳机,rating:4.2},{id:4,name:iPad,price:4999,category:平板,rating:4.6}]);const[filters,setFilters]useStateFilterOptions({category:,minPrice:0,maxPrice:99999,searchQuery:});// 使用useMemo缓存过滤结果constfilteredProductsuseMemo((){console.log(执行产品过滤计算);returnproducts.filter(product{constcategoryMatch!filters.category||product.categoryfilters.category;constpriceMatchproduct.pricefilters.minPriceproduct.pricefilters.maxPrice;constsearchMatch!filters.searchQuery||product.name.toLowerCase().includes(filters.searchQuery.toLowerCase());returncategoryMatchpriceMatchsearchMatch;});},[products,filters]);// 使用useMemo缓存统计信息conststatsuseMemo((){consttotalProductsfilteredProducts.length;constavgPricetotalProducts0?filteredProducts.reduce((sum,p)sump.price,0)/totalProducts:0;constavgRatingtotalProducts0?filteredProducts.reduce((sum,p)sump.rating,0)/totalProducts:0;return{totalProducts,avgPrice,avgRating};},[filteredProducts]);// 使用useMemo缓存分类列表constcategoriesuseMemo((){constcatsArray.from(newSet(products.map(pp.category)));return[全部,...cats];},[products]);// 使用useMemo缓存事件处理函数consthandleFilterChangeuseCallback((field:keyofFilterOptions,value:string|number){setFilters(prev({...prev,[field]:value}));},[]);// 使用useCallback缓存重置函数constresetFiltersuseCallback((){setFilters({category:,minPrice:0,maxPrice:99999,searchQuery:});},[]);console.log(ProductApp 重新渲染);return(divh1产品商店/h1{/* 统计信息 */}divp总产品数:{stats.totalProducts}/pp平均价格:¥{stats.avgPrice.toFixed(2)}/pp平均评分:{stats.avgRating.toFixed(1)}/p/div{/* ️ 过滤控件 */}divselect value{filters.category}onChange{(e)handleFilterChange(category,e.target.value)}{categories.map(category(option key{category}value{category全部?:category}{category}/option))}/selectinputtypenumberplaceholder最低价格value{filters.minPrice}onChange{(e)handleFilterChange(minPrice,Number(e.target.value))}/inputtypenumberplaceholder最高价格value{filters.maxPrice}onChange{(e)handleFilterChange(maxPrice,Number(e.target.value))}/inputtypetextplaceholder搜索产品value{filters.searchQuery}onChange{(e)handleFilterChange(searchQuery,e.target.value)}/button onClick{resetFilters}重置/button/div{/* 产品列表 */}ProductList products{filteredProducts}//div);};6️⃣ useRef HookDOM引用与可变值importReact,{useRef,useEffect,useState}fromreact;// ️ DOM引用示例constDomRefExample:React.FC(){constinputRefuseRefHTMLInputElement(null);constvideoRefuseRefHTMLVideoElement(null);constcanvasRefuseRefHTMLCanvasElement(null);// ️ 聚焦输入框constfocusInput(){inputRef.current?.focus();};// 播放/暂停视频consttoggleVideo(){constvideovideoRef.current;if(video){if(video.paused){video.play();}else{video.pause();}}};// Canvas绘图constdrawCanvas(){constcanvascanvasRef.current;if(!canvas)return;constctxcanvas.getContext(2d);if(!ctx)return;ctx.fillStyle#007bff;ctx.fillRect(10,10,100,50);ctx.fillStyle#28a745;ctx.fillRect(120,10,100,50);};// 测量DOM元素constmeasureElement(){constinputinputRef.current;if(input){constrectinput.getBoundingClientRect();console.log(输入框尺寸:,{width:rect.width,height:rect.height,top:rect.top,left:rect.left});}};return(divh2DOM引用示例/h2divinput ref{inputRef}typetextplaceholder聚焦测试/button onClick{focusInput}聚焦输入框/buttonbutton onClick{measureElement}测量元素/button/divdivvideo ref{videoRef}width300controls srchttps://example.com/video.mp4/button onClick{toggleVideo}播放/暂停/button/divdivcanvas ref{canvasRef}width250height100style{{border:1px solid #ccc}}/button onClick{drawCanvas}绘制图形/button/div/div);};// 可变值引用示例constMutableRefExample:React.FC(){const[count,setCount]useState(0);constrenderCountRefuseRef(0);constintervalRefuseRefNodeJS.Timeout|null(null);constpreviousCountRefuseRefnumber(0);// 渲染计数器renderCountRef.current1;// ⏰ 定时器示例conststartTimer(){if(intervalRef.currentnull){intervalRef.currentsetInterval((){console.log(定时器执行:,newDate().toLocaleTimeString());},1000);}};conststopTimer(){if(intervalRef.current!null){clearInterval(intervalRef.current);intervalRef.currentnull;}};// 跟踪前一个值useEffect((){console.log(Count从${previousCountRef.current}变为${count});previousCountRef.currentcount;},[count]);// 清理定时器useEffect((){return(){if(intervalRef.current!null){clearInterval(intervalRef.current);}};},[]);return(divh2可变值引用示例/h2p当前Count:{count}/pp渲染次数:{renderCountRef.current}/pbutton onClick{()setCount(count1)}增加Count/buttonbutton onClick{startTimer}开始定时器/buttonbutton onClick{stopTimer}停止定时器/button/div);};7️⃣ useLayoutEffect Hook同步副作用importReact,{useState,useLayoutEffect,useRef}fromreact;constLayoutEffectExample:React.FC(){const[dimensions,setDimensions]useState({width:0,height:0});constdivRefuseRefHTMLDivElement(null);// 同步测量布局useLayoutEffect((){if(divRef.current){constrectdivRef.current.getBoundingClientRect();setDimensions({width:rect.width,height:rect.height});}},[]);// 防闪烁的DOM操作const[visible,setVisible]useState(false);useLayoutEffect((){// 在浏览器重绘前更新样式避免闪烁if(visibledivRef.current){divRef.current.style.opacity0;// 强制重排divRef.current.offsetHeight;// 触发动画divRef.current.style.transitionopacity 0.3s;divRef.current.style.opacity1;}},[visible]);return(divh2useLayoutEffect示例/h2p元素尺寸:{dimensions.width}x{dimensions.height}/pdivbutton onClick{()setVisible(!visible)}{visible?隐藏:显示}元素/button{visible(div ref{divRef}style{{width:200px,height:100px,backgroundColor:#007bff,color:white,display:flex,alignItems:center,justifyContent:center}}动画元素/div)}/div/div);}; 自定义Hooks开发指南 自定义Hook设计原则 命名规范必须以’use’开头 参数设计提供灵活的配置选项 返回值合理的类型定义和结构️ 错误处理完善的错误边界和异常处理⚡ 性能优化合理使用缓存和优化技巧 数据获取Hookimport{useState,useEffect,useCallback}fromreact;// 通用数据获取HookinterfaceUseApiResultT{data:T|null;loading:boolean;error:string|null;refetch:()Promisevoid;}interfaceUseApiOptions{immediate?:boolean;onSuccess?:(data:any)void;onError?:(error:string)void;}functionuseApiT(apiCall:()PromiseT,deps:React.DependencyList[],options:UseApiOptions{}):UseApiResultT{const{immediatetrue,onSuccess,onError}options;const[data,setData]useStateT|null(null);const[loading,setLoading]useStateboolean(immediate);const[error,setError]useStatestring|null(null);constfetchDatauseCallback(async(){try{setLoading(true);setError(null);constresultawaitapiCall();setData(result);onSuccess?.(result);}catch(err){consterrorMessageerrinstanceofError?err.message:未知错误;setError(errorMessage);onError?.(errorMessage);}finally{setLoading(false);}},[apiCall,onSuccess,onError]);useEffect((){if(immediate){fetchData();}},deps);return{data,loading,error,refetch:fetchData};}// 使用示例constPostComponent:React.FC(){const{data:posts,loading,error,refetch}useApi(()fetch(https://api.example.com/posts).then(resres.json()),[],{immediate:true,onSuccess:(data)console.log(获取成功:,data),onError:(error)console.error(获取失败:,error)});if(loading)returndiv加载中.../div;if(error)returndiv错误:{error}/div;return(divbutton onClick{refetch}刷新数据/button{/* 渲染数据 */}/div);}; 表单管理Hookimport{useState,useCallback}fromreact;// 表单字段类型interfaceFormFieldT{value:T;error:string;touched:boolean;dirty:boolean;}// 表单值类型interfaceFormValuesTextendsRecordstring,any{[KinkeyofT]:FormFieldT[K];}// ️ 验证规则类型interfaceValidationRuleT{required?:boolean;min?:number;max?:number;pattern?:RegExp;custom?:(value:T)string|null;}// 表单配置类型interfaceFormConfigTextendsRecordstring,any{initialValues:T;validationRules?:{[KinkeyofT]?:ValidationRuleT[K];};onSubmit:(values:T)void|Promisevoid;}// 自定义表单HookfunctionuseFormTextendsRecordstring,any(config:FormConfigT){const{initialValues,validationRules,onSubmit}config;// 初始化表单状态const[formValues,setFormValues]useStateFormValuesT((){constinitial:any{};Object.keys(initialValues).forEach(key{initial[key]{value:initialValues[keyaskeyofT],error:,touched:false,dirty:false};});returninitial;});const[isSubmitting,setIsSubmitting]useState(false);// 字段验证constvalidateFielduseCallback((fieldName:keyofT,value:any):string{construlesvalidationRules?.[fieldName];if(!rules)return;if(rules.required(!value||value.toString().trim())){return此字段为必填项;}if(typeofvaluestring){if(rules.minvalue.lengthrules.min){return最少需要${rules.min}个字符;}if(rules.maxvalue.lengthrules.max){return最多允许${rules.max}个字符;}if(rules.pattern!rules.pattern.test(value)){return格式不正确;}}if(typeofvaluenumber){if(rules.min!undefinedvaluerules.min){return值不能小于${rules.min};}if(rules.max!undefinedvaluerules.max){return值不能大于${rules.max};}}if(rules.custom){returnrules.custom(value)||;}return;},[validationRules]);// 值变更处理constsetValueuseCallback((fieldName:keyofT,value:any){setFormValues(prev({...prev,[fieldName]:{...prev[fieldName],value,dirty:true,error:prev[fieldName].touched?validateField(fieldName,value):prev[fieldName].error}}));},[validateField]);// ️ 字段失焦处理consthandleBluruseCallback((fieldName:keyofT){setFormValues(prev({...prev,[fieldName]:{...prev[fieldName],touched:true,error:validateField(fieldName,prev[fieldName].value)}}));},[validateField]);// 获取表单值constgetValuesuseCallback(():T{constvalues:any{};Object.keys(formValues).forEach(key{values[keyaskeyofT]formValues[keyaskeyofT].value;});returnvalues;},[formValues]);// ✅ 表单验证constvalidateFormuseCallback(():boolean{letisValidtrue;constnewFormValues{...formValues};Object.keys(formValues).forEach(fieldName{constfieldformValues[fieldNameaskeyofT];consterrorvalidateField(fieldNameaskeyofT,field.value);newFormValues[fieldNameaskeyofT]{...field,error,touched:true};if(error)isValidfalse;});setFormValues(newFormValues);returnisValid;},[formValues,validateField]);// 提交处理consthandleSubmituseCallback(async(e?:React.FormEvent){e?.preventDefault();if(!validateForm())return;setIsSubmitting(true);try{awaitonSubmit(getValues());}catch(error){console.error(表单提交失败:,error);}finally{setIsSubmitting(false);}},[validateForm,getValues,onSubmit]);// 重置表单constresetFormuseCallback((){constreset:any{};Object.keys(initialValues).forEach(key{reset[key]{value:initialValues[keyaskeyofT],error:,touched:false,dirty:false};});setFormValues(reset);},[initialValues]);return{formValues,setValue,handleBlur,handleSubmit,resetForm,isSubmitting,isValid:Object.values(formValues).every(field!field.error)};}// 使用示例constLoginForm:React.FC(){const{formValues,setValue,handleBlur,handleSubmit,resetForm,isSubmitting,isValid}useForm({initialValues:{email:,password:,rememberMe:false},validationRules:{email:{required:true,pattern:/^[^\s][^\s]\.[^\s]$/,custom:(value:string){if(!value.endsWith(example.com)){return邮箱必须以 example.com 结尾;}returnnull;}},password:{required:true,min:8,max:20}},onSubmit:async(values){console.log(提交表单:,values);// 模拟API调用awaitnewPromise(resolvesetTimeout(resolve,1000));alert(登录成功);}});return(form onSubmit{handleSubmit}divinputtypeemailplaceholder邮箱value{formValues.email.value}onChange{(e)setValue(email,e.target.value)}onBlur{()handleBlur(email)}/{formValues.email.error(span style{{color:red}}{formValues.email.error}/span)}/divdivinputtypepasswordplaceholder密码value{formValues.password.value}onChange{(e)setValue(password,e.target.value)}onBlur{()handleBlur(password)}/{formValues.password.error(span style{{color:red}}{formValues.password.error}/span)}/divdivlabelinputtypecheckboxchecked{formValues.rememberMe.value}onChange{(e)setValue(rememberMe,e.target.checked)}/记住我/label/divbuttontypesubmitdisabled{isSubmitting||!isValid}{isSubmitting?登录中...:登录}/buttonbuttontypebuttononClick{resetForm}重置/button/form);}; 本地存储Hookimport{useState,useEffect,useCallback}fromreact;// 本地存储HookinterfaceUseLocalStorageOptionsT{serializer?:{read:(value:string)T;write:(value:T)string;};}functionuseLocalStorageT(key:string,initialValue:T,options:UseLocalStorageOptionsT{}){const{serializer}options;// 读取存储值constreadValueuseCallback(():T{try{constitemwindow.localStorage.getItem(key);if(itemnull){returninitialValue;}returnserializer?serializer.read(item):JSON.parse(item);}catch(error){console.warn(Error reading localStorage key ${key}:,error);returninitialValue;}},[key,initialValue,serializer]);const[storedValue,setStoredValue]useStateT(readValue);// 设置存储值constsetValueuseCallback((value:T|((val:T)T)){try{constvalueToStorevalueinstanceofFunction?value(storedValue):value;setStoredValue(valueToStore);window.localStorage.setItem(key,serializer?serializer.write(valueToStore):JSON.stringify(valueToStore));}catch(error){console.warn(Error setting localStorage key ${key}:,error);}},[key,storedValue,serializer]);// ️ 删除存储值constremoveValueuseCallback((){try{window.localStorage.removeItem(key);setStoredValue(initialValue);}catch(error){console.warn(Error removing localStorage key ${key}:,error);}},[key,initialValue]);// 监听存储变化useEffect((){consthandleStorageChange(e:StorageEvent){if(e.keykeye.newValue!null){try{constnewValueserializer?serializer.read(e.newValue):JSON.parse(e.newValue);setStoredValue(newValue);}catch(error){console.warn(Error parsing storage value for key ${key}:,error);}}};window.addEventListener(storage,handleStorageChange);return()window.removeEventListener(storage,handleStorageChange);},[key,serializer]);return[storedValue,setValue,removeValue]asconst;}// 使用示例constStorageExample:React.FC(){const[name,setName,removeName]useLocalStorage(username,);const[settings,setSettings]useLocalStorage(appSettings,{theme:lightaslight|dark,language:zh-CN,notifications:true});return(divh2本地存储示例/h2divh3用户名存储/h3inputtypetextvalue{name}onChange{(e)setName(e.target.value)}placeholder输入用户名/p存储的用户名:{name}/pbutton onClick{()removeName()}清除用户名/button/divdivh3应用设置/h3select value{settings.theme}onChange{(e)setSettings({...settings,theme:e.target.valueaslight|dark})}option valuelight浅色主题/optionoption valuedark深色主题/option/selectselect value{settings.language}onChange{(e)setSettings({...settings,language:e.target.value})}option valuezh-CN中文/optionoption valueen-USEnglish/option/selectlabelinputtypecheckboxchecked{settings.notifications}onChange{(e)setSettings({...settings,notifications:e.target.checked})}/启用通知/labelpre{JSON.stringify(settings,null,2)}/pre/div/div);}; 防抖/节流Hookimport{useState,useEffect,useCallback,useRef}fromreact;// 防抖HookfunctionuseDebounceT(value:T,delay:number):T{const[debouncedValue,setDebouncedValue]useStateT(value);useEffect((){consthandlersetTimeout((){setDebouncedValue(value);},delay);return(){clearTimeout(handler);};},[value,delay]);returndebouncedValue;}// 节流HookfunctionuseThrottleTextends(...args:any[])any(fn:T,delay:number):T{constlastCalluseRefnumber(0);returnuseCallback(((...args:ParametersT){constnowDate.now();if(now-lastCall.currentdelay){lastCall.currentnow;returnfn(...args);}})asT,[fn,delay]);}// 防抖函数HookfunctionuseDebouncedCallbackTextends(...args:any[])any(callback:T,delay:number):T{constcallbackRefuseRef(callback);consttimeoutRefuseRefNodeJS.Timeout();useEffect((){callbackRef.currentcallback;},[callback]);returnuseCallback(((...args:ParametersT){if(timeoutRef.current){clearTimeout(timeoutRef.current);}timeoutRef.currentsetTimeout((){callbackRef.current(...args);},delay);})asT,[delay]);}// 使用示例constDebounceThrottleExample:React.FC(){const[searchTerm,setSearchTerm]useState();const[searchResults,setSearchResults]useStatestring[]([]);// 防抖搜索constdebouncedSearchTermuseDebounce(searchTerm,500);// 防抖搜索函数constdebouncedSearchuseDebouncedCallback((term:string){console.log(执行搜索:,term);// 模拟API搜索setSearchResults([${term}- 结果1,${term}- 结果2,${term}- 结果3]);},500);// 节流滚动处理constthrottledScrolluseThrottle((){console.log(滚动事件:,window.scrollY);},100);// 响应防抖搜索useEffect((){if(debouncedSearchTerm){debouncedSearch(debouncedSearchTerm);}else{setSearchResults([]);}},[debouncedSearchTerm,debouncedSearch]);// ️ 滚动事件监听useEffect((){window.addEventListener(scroll,throttledScroll);return()window.removeEventListener(scroll,throttledScroll);},[throttledScroll]);// 节流按钮点击constthrottledClickuseThrottle((){console.log(按钮点击:,newDate().toLocaleTimeString());},1000);return(div style{{height:200vh}}h2防抖/节流示例/h2divh3防抖搜索/h3inputtypetextplaceholder搜索内容...value{searchTerm}onChange{(e)setSearchTerm(e.target.value)}/p输入值:{searchTerm}/pp防抖值:{debouncedSearchTerm}/p{searchResults.length0(ul{searchResults.map((result,index)(li key{index}{result}/li))}/ul)}/divdivh3节流按钮/h3button onClick{throttledClick}节流点击(1秒内只执行一次)/button/divdiv style{{position:fixed,top:20,right:20,background:#fff,padding:10px}}h3滚动位置:{Math.round(window.scrollY)}/h3/div/div);};⚡ 性能优化技巧 性能优化策略矩阵优化类型️具体技巧性能提升⚡适用场景 组件渲染React.memo, useMemo, useCallback 30-70%频繁重渲染组件 数据处理缓存计算, 虚拟化, 分页 50-90%大数据列表 DOM操作批量更新, 节流防抖⚡ 20-50%频繁DOM操作 包大小代码分割, Tree Shaking 40-80%大型应用 渲染优化技巧importReact,{useState,useMemo,useCallback,memo,ReactNode}fromreact;// 优化的子组件constOptimizedChildmemo{data:number;onUpdate:(value:number)void;title:string;children?:ReactNode;}(({data,onUpdate,title,children}){console.log(优化子组件渲染:${title});return(div style{{border:1px solid #ccc,padding:10px,margin:5px}}h4{title}/h4p数据:{data}/pbutton onClick{()onUpdate(data1)}增加/button{children}/div);});// 比较函数优化constareEqual(prevProps:any,nextProps:any){return(prevProps.datanextProps.dataprevProps.titlenextProps.title);};constHighlyOptimizedChildmemo(({data,onUpdate,title}:any){console.log(高度优化子组件渲染:${title});return(div style{{border:1px solid #007bff,padding:10px,margin:5px}}h4{title}/h4p数据:{data}/pbutton onClick{()onUpdate(data1)}增加/button/div);},areEqual);// ️ 父组件constPerformanceOptimization:React.FC(){const[count1,setCount1]useState(0);const[count2,setCount2]useState(0);const[name,setName]useState();// 使用useCallback缓存事件处理函数consthandleUpdate1useCallback((value:number){setCount1(value);},[]);consthandleUpdate2useCallback((value:number){setCount2(value);},[]);// 使用useMemo缓存计算结果constexpensiveValueuseMemo((){console.log(执行复杂计算);letresult0;for(leti0;i1000000;i){resultMath.sqrt(i);}returnMath.round(result);},[]);// 空依赖数组只在首次渲染时计算// 缓存对象类型数据constconfiguseMemo(()({theme:light,version:1.0.0,timestamp:Date.now()}),[]);// 缓存复杂计算函数constcalculateFactorialuseCallback((n:number):number{if(n1)return1;returnn*calculateFactorial(n-1);},[]);constfactorialuseMemo((){returncalculateFactorial(10);},[calculateFactorial]);console.log(父组件渲染);return(divh2性能优化示例/h2divh3基础状态管理/h3p计数器1:{count1}/pp计数器2:{count2}/pinputtypetextvalue{name}onChange{(e)setName(e.target.value)}placeholder输入名字//divdivh3优化的子组件/h3OptimizedChild data{count1}onUpdate{handleUpdate1}title优化子组件1/OptimizedChild data{count2}onUpdate{handleUpdate2}title优化子组件2/HighlyOptimizedChild data{count1}onUpdate{handleUpdate1}title高度优化子组件//divdivh3计算缓存/h3p复杂计算结果:{expensiveValue}/pp10的阶乘:{factorial}/ppre{JSON.stringify(config,null,2)}/pre/div/div);}; 虚拟滚动优化importReact,{useState,useMemo,useCallback,useRef,useEffect}fromreact;// 虚拟滚动HookinterfaceUseVirtualScrollOptions{itemHeight:number;containerHeight:number;overscan?:number;}functionuseVirtualScrollT(items:T[],options:UseVirtualScrollOptions){const{itemHeight,containerHeight,overscan5}options;const[scrollTop,setScrollTop]useState(0);constvisibleRangeuseMemo((){conststartIndexMath.max(0,Math.floor(scrollTop/itemHeight)-overscan);constendIndexMath.min(items.length-1,Math.ceil((scrollTopcontainerHeight)/itemHeight)overscan);return{startIndex,endIndex};},[scrollTop,itemHeight,containerHeight,overscan,items.length]);constvisibleItemsuseMemo((){returnitems.slice(visibleRange.startIndex,visibleRange.endIndex1).map((item,index)({item,index:visibleRange.startIndexindex}));},[items,visibleRange]);constcontainerStyleuseMemo(()({height:containerHeight,overflow:auto}),[containerHeight]);constcontentStyleuseMemo(()({height:items.length*itemHeight,position:relativeasconst}),[items.length,itemHeight]);constgetItemStyleuseCallback((index:number)({position:absoluteasconst,top:index*itemHeight,left:0,right:0,height:itemHeight}),[itemHeight]);consthandleScrolluseCallback((e:React.UIEventHTMLDivElement){setScrollTop(e.currentTarget.scrollTop);},[]);return{visibleItems,containerStyle,contentStyle,getItemStyle,handleScroll,totalHeight:items.length*itemHeight};}// 虚拟滚动组件interfaceVirtualListPropsT{items:T[];itemHeight:number;containerHeight:number;renderItem:(item:T,index:number)ReactNode;getItemKey?:(item:T,index:number)string|number;}functionVirtualListT({items,itemHeight,containerHeight,renderItem,getItemKey}:VirtualListPropsT){const{visibleItems,containerStyle,contentStyle,getItemStyle,handleScroll}useVirtualScroll(items,{itemHeight,containerHeight});return(div style{containerStyle}onScroll{handleScroll}div style{contentStyle}{visibleItems.map(({item,index})(div key{getItemKey?getItemKey(item,index):index}style{getItemStyle(index)}{renderItem(item,index)}/div))}/div/div);}// 使用示例interfaceDataItem{id:number;name:string;value:number;description:string;}constVirtualScrollExample:React.FC(){const[data]useStateDataItem((){returnArray.from({length:10000},(_,index)({id:index1,name:项目${index1},value:Math.floor(Math.random()*1000),description:这是第${index1}个项目的详细描述信息包含了很多文字内容。}));});constrenderDataItemuseCallback((item:DataItem,index:number)(div style{{border:1px solid #ddd,padding:10px,backgroundColor:index%20?#f9f9f9:#fff}}h4{item.name}/h4pID:{item.id}|值:{item.value}/pp{item.description}/p/div),[]);constgetItemKeyuseCallback((item:DataItem)item.id,[]);return(divh2虚拟滚动示例/h2p总共{data.length}项数据/pVirtualList items{data}itemHeight{120}containerHeight{400}renderItem{renderDataItem}getItemKey{getItemKey}//div);}; 实战项目案例 完整的任务管理应用importReact,{useState,useEffect,useReducer,useCallback,useMemo,createContext,useContext}fromreact;// 任务类型定义interfaceTask{id:string;title:string;description:string;completed:boolean;priority:low|medium|high;dueDate:Date|null;tags:string[];createdAt:Date;updatedAt:Date;}interfaceTaskState{tasks:Task[];filter:{status:all|active|completed;priority:all|low|medium|high;searchTerm:string;sortBy:dueDate|priority|createdAt|title;sortOrder:asc|desc;};loading:boolean;error:string|null;}// Action类型typeTaskAction|{type:SET_LOADING;payload:boolean}|{type:SET_ERROR;payload:string|null}|{type:SET_TASKS;payload:Task[]}|{type:ADD_TASK;payload:Task}|{type:UPDATE_TASK;payload:{id:string;updates:PartialTask}}|{type:DELETE_TASK;payload:string}|{type:SET_FILTER;payload:PartialTaskState[filter]};// ️ Task ReducerconsttaskReducer(state:TaskState,action:TaskAction):TaskState{switch(action.type){caseSET_LOADING:return{...state,loading:action.payload};caseSET_ERROR:return{...state,error:action.payload};caseSET_TASKS:return{...state,tasks:action.payload,loading:false};caseADD_TASK:return{...state,tasks:[...state.tasks,action.payload]};caseUPDATE_TASK:return{...state,tasks:state.tasks.map(tasktask.idaction.payload.id?{...task,...action.payload.updates,updatedAt:newDate()}:task)};caseDELETE_TASK:return{...state,tasks:state.tasks.filter(tasktask.id!action.payload)};caseSET_FILTER:return{...state,filter:{...state.filter,...action.payload}};default:returnstate;}};// ️ ContextconstTaskContextcreateContext{state:TaskState;dispatch:React.DispatchTaskAction;}|null(null);// Task ProviderconstTaskProvider:React.FC{children:React.ReactNode}({children}){const[state,dispatch]useReducer(taskReducer,{tasks:[],filter:{status:all,priority:all,searchTerm:,sortBy:createdAt,sortOrder:desc},loading:false,error:null});// 数据加载EffectuseEffect((){constloadTasksasync(){dispatch({type:SET_LOADING,payload:true});try{// 模拟API调用awaitnewPromise(resolvesetTimeout(resolve,1000));constmockTasks:Task[][{id:1,title:完成项目文档,description:编写详细的项目文档和API说明,completed:false,priority:high,dueDate:newDate(Date.now()3*24*60*60*1000),tags:[文档,项目],createdAt:newDate(),updatedAt:newDate()},{id:2,title:代码审查,description:审查团队成员提交的代码,completed:true,priority:medium,dueDate:newDate(Date.now()1*24*60*60*1000),tags:[代码,团队],createdAt:newDate(Date.now()-2*24*60*60*1000),updatedAt:newDate()}];dispatch({type:SET_TASKS,payload:mockTasks});}catch(error){dispatch({type:SET_ERROR,payload:加载任务失败});}};loadTasks();},[]);return(TaskContext.Provider value{{state,dispatch}}{children}/TaskContext.Provider);};// useTask HookconstuseTask(){constcontextuseContext(TaskContext);if(!context){thrownewError(useTask must be used within a TaskProvider);}returncontext;};// 过滤和排序HookconstuseFilteredTasks(){const{state}useTask();constfilteredTasksuseMemo((){lettasks[...state.tasks];// 状态过滤if(state.filter.statusactive){taskstasks.filter(task!task.completed);}elseif(state.filter.statuscompleted){taskstasks.filter(tasktask.completed);}// 优先级过滤if(state.filter.priority!all){taskstasks.filter(tasktask.prioritystate.filter.priority);}// 搜索过滤if(state.filter.searchTerm){constsearchTermstate.filter.searchTerm.toLowerCase();taskstasks.filter(tasktask.title.toLowerCase().includes(searchTerm)||task.description.toLowerCase().includes(searchTerm)||task.tags.some(tagtag.toLowerCase().includes(searchTerm)));}// 排序tasks.sort((a,b){letaValue:any,bValue:any;switch(state.filter.sortBy){casedueDate:aValuea.dueDate?.getTime()||Infinity;bValueb.dueDate?.getTime()||Infinity;break;casepriority:constpriorityOrder{low:1,medium:2,high:3};aValuepriorityOrder[a.priority];bValuepriorityOrder[b.priority];break;casetitle:aValuea.title.toLowerCase();bValueb.title.toLowerCase();break;casecreatedAt:default:aValuea.createdAt.getTime();bValueb.createdAt.getTime();break;}if(state.filter.sortOrderasc){returnaValuebValue?1:aValuebValue?-1:0;}else{returnaValuebValue?1:aValuebValue?-1:0;}});returntasks;},[state.tasks,state.filter]);returnfilteredTasks;};// ️ 任务统计HookconstuseTaskStats(){consttasksuseFilteredTasks();returnuseMemo((){consttotaltasks.length;constcompletedtasks.filter(tasktask.completed).length;constactivetotal-completed;constpriorityStats{high:tasks.filter(tasktask.priorityhigh).length,medium:tasks.filter(tasktask.prioritymedium).length,low:tasks.filter(tasktask.prioritylow).length};return{total,completed,active,priorityStats};},[tasks]);};// ️ 任务组件constTaskItem:React.FC{task:Task}React.memo(({task}){const{dispatch}useTask();consttoggleCompleteuseCallback((){dispatch({type:UPDATE_TASK,payload:{id:task.id,updates:{completed:!task.completed}}});},[task.id,task.completed,dispatch]);constdeleteTaskuseCallback((){if(window.confirm(确定要删除这个任务吗)){dispatch({type:DELETE_TASK,payload:task.id});}},[task.id,dispatch]);constpriorityColors{high:#dc3545,medium:#ffc107,low:#28a745};return(div style{{border:1px solid #ddd,borderRadius:8px,padding:15px,margin:10px 0,backgroundColor:task.completed?#f8f9fa:#fff}}div style{{display:flex,justifyContent:space-between,alignItems:center}}div style{{flex:1}}h3 style{{margin:0,textDecoration:task.completed?line-through:none,color:task.completed?#6c757d:#212529}}{task.title}/h3p style{{margin:5px 0,color:#6c757d}}{task.description}/pdiv style{{display:flex,gap:10px,flexWrap:wrap}}{task.tags.map(tag(span key{tag}style{{backgroundColor:#e9ecef,padding:2px 8px,borderRadius:12px,fontSize:12px}}{tag}/span))}span style{{backgroundColor:priorityColors[task.priority],color:white,padding:2px 8px,borderRadius:12px,fontSize:12px}}{task.priority}/span/div{task.dueDate(p style{{margin:5px 0,fontSize:14px}}截止日期:{task.dueDate.toLocaleDateString()}/p)}/divdiv style{{display:flex,gap:10px}}button onClick{toggleComplete}style{{backgroundColor:task.completed?#28a745:#ffc107,border:none,color:white,padding:8px 16px,borderRadius:4px,cursor:pointer}}{task.completed?已完成:未完成}/buttonbutton onClick{deleteTask}style{{backgroundColor:#dc3545,border:none,color:white,padding:8px 16px,borderRadius:4px,cursor:pointer}}删除/button/div/div/div);});// ️ 任务列表组件constTaskList:React.FC(){consttasksuseFilteredTasks();const{state,dispatch}useTask();conststatsuseTaskStats();consthandleFilterChangeuseCallback((updates:PartialTaskState[filter]){dispatch({type:SET_FILTER,payload:updates});},[dispatch]);if(state.loading)returndiv加载中.../div;if(state.error)returndiv错误:{state.error}/div;return(divh2任务管理/h2{/* 统计信息 */}div style{{display:grid,gridTemplateColumns:repeat(auto-fit, minmax(150px, 1fr)),gap:10px,marginBottom:20px}}div style{{padding:15px,backgroundColor:#e3f2fd,borderRadius:8px}}h4总任务/h4p style{{fontSize:24px,margin:0}}{stats.total}/p/divdiv style{{padding:15px,backgroundColor:#e8f5e8,borderRadius:8px}}h4已完成/h4p style{{fontSize:24px,margin:0}}{stats.completed}/p/divdiv style{{padding:15px,backgroundColor:#fff3e0,borderRadius:8px}}h4进行中/h4p style{{fontSize:24px,margin:0}}{stats.active}/p/div/div{/* ️ 过滤器 */}div style{{display:grid,gridTemplateColumns:repeat(auto-fit, minmax(150px, 1fr)),gap:10px,marginBottom:20px,padding:15px,backgroundColor:#f8f9fa,borderRadius:8px}}select value{state.filter.status}onChange{(e)handleFilterChange({status:e.target.valueasany})}option valueall全部状态/optionoption valueactive进行中/optionoption valuecompleted已完成/option/selectselect value{state.filter.priority}onChange{(e)handleFilterChange({priority:e.target.valueasany})}option valueall全部优先级/optionoption valuehigh高/optionoption valuemedium中/optionoption valuelow低/option/selectinputtypetextplaceholder搜索任务...value{state.filter.searchTerm}onChange{(e)handleFilterChange({searchTerm:e.target.value})}/select value{state.filter.sortBy}onChange{(e)handleFilterChange({sortBy:e.target.valueasany})}option valuecreatedAt创建时间/optionoption valuedueDate截止日期/optionoption valuepriority优先级/optionoption valuetitle标题/option/selectselect value{state.filter.sortOrder}onChange{(e)handleFilterChange({sortOrder:e.target.valueasany})}option valuedesc降序/optionoption valueasc升序/option/select/div{/* 任务列表 */}div{tasks.length0?(p style{{textAlign:center,color:#6c757d}}没有找到匹配的任务/p):(tasks.map(taskTaskItem key{task.id}task{task}/))}/div/div);};// ️ 主应用组件constTaskManagementApp:React.FC(){return(TaskProviderdiv style{{maxWidth:800px,margin:0 auto,padding:20px}}TaskList//div/TaskProvider);};exportdefaultTaskManagementApp; 总结与最佳实践 核心要点回顾mindmap root((React Hooks TypeScript)) 内置Hooks useState 状态管理 useEffect 副作用处理 useContext 上下文访问 useReducer 复杂状态 useMemo 缓存计算 useCallback 缓存函数 useRef DOM引用 useLayoutEffect 同步副作用 自定义Hooks 数据获取 表单管理 本地存储 防抖节流 业务逻辑复用 性能优化 组件优化 渲染优化 内存优化 包大小优化 最佳实践 类型安全 错误处理 测试策略 架构设计 最佳实践指南实践领域具体建议⭐重要性实施难度 类型安全严格TypeScript配置完整类型定义⭐⭐⭐⭐⭐ 简单 状态管理合理选择useState/useReducer⭐⭐⭐⭐ 中等⚡ 性能优化适度使用memo/useMemo/useCallback⭐⭐⭐⭐ 中等️ 错误处理完善的边界和异常处理⭐⭐⭐⭐⭐ 中等 测试覆盖单元测试集成测试⭐⭐⭐ 中等 进阶学习路径 深入理解React原理Fiber架构调度和协调机制Hooks实现原理 高级状态管理Redux ToolkitZustandJotai⚡ 性能优化进阶Concurrent ModeSuspenseServer Components