当前位置: 首页 > 后端技术 > Node.js

React移动端和PC端生态使用总结

时间:2023-04-03 11:48:37 Node.js

对于一项技术,我们不可能在状态中停留五分钟。特别喜欢一句话。使用什么方法绘制UI界面并不重要。重要的是潜在的思想。解决问题和优化的想法。由于React庞大的生态系统,本文部分内容来自他人的总结。只要还能找到原文,我就把地址贴出来。感谢早前贡献的作者。如果有任何总结,请在下面添加。生态系统:React官方推荐超大型项目使用TypeScript。为什么要把TypeScript放在第一位,因为TypeScript在构建超大型应用时,多人协作可以大大加快工作效率,尤其是前后端交互比较多的时候。当业务情况特别复杂时(如IM),其优势就凸显出来。但在一些中小型项目中,优势并不那么明显。(比如做完项目以后不要再迭代)TypeScript不是一门新的语言,你可以简单的认为TS=js+Type。只是javascript的超集,目前更新速度也很快。个人建议,在Node.js开发中使用TypeScript和React原生和大型React下载官方的react脚手架,包括第三方ts命令创建脚手架在CreateReactApp中使用TypeScriptCreateReactApp内置了对TypeScript的支持`。需要使用TypeScript创建一个新项目,在终端运行:npxcreate-react-appmy-app--typescriptinterfaceIState{collapsed?:boolean,}interfaceIProps{props?:string|Function}constructor(props:IState){super(props)}flag:number=123componentDidMount(){constresult=this.FunctionTest()}FunctionTest():Promise{返回Promise.resolve(false)}TypeScript写的代码量会多一些,但是对于参数类型和返回类型,一目了然,有静态类型检查,如果有问题,写代码的时候就知道了.再补充一点,TS的生态现在适合发展。常见的webpack插件都有typescript文件支持。当然,并不是所有的第三方包都支持ts。这个在选择技术的时候一定要考虑清楚,否则会做很多工作。统一集中管理状态,开源库如redux,mbox,redux-sage,dva等。先看看原来的react数据管理组件数据传递,依赖props,state数据提升等,但是对于跨-组件间的数据级传递,不是那么友好,尤其是大型项目后期的迭代维护,被人吐槽,但其单向数据流的思想不得不得到redux的肯定。Redux状态和页面逻辑从中提取出来成为独立的store,页面逻辑是reducer都是PureComponents,你可以很容易地通过connect方法给它们加上一层wrapper与store建立连接:可以通过dispatch向store注入action,提示store的状态发生变化,同时订阅store的状态变化。一旦状态改变,连接的组件也会被刷新。使用dispatch发送一个action到store的过程是可以拦截的,可以很自然的在这里添加各种中间件实现各种自定义功能,eg:logging这样,各部分各司其职,度耦合度更低,可重用度更高,扩展性更好。面试的时候,我觉得如果能手写一个redux库,把单向数据流的思路说清楚,是加分项。最后推荐dva,感谢前辈的开源,解放了我们的dva。正如Dva官网所说,Dva基于React+Redux+Saga的最佳实践沉淀。它做了3件很重要的事情,大大提升了编码体验//一个dva模块文件user.jsexportdefault{namespace:'userinfo',state:{width:'-100%',hasUserInfoActive:false,info:undefined,},reducers:{//打开个人数据open(state){return{...state,width:'0%',hasUserInfoActive:true,};},},效果:{*init(res,{put,select}){const{userinfo}=yieldselect();if(userinfo.info===undefined){try{constlist=yieldDATABASE.Friend().getSelfInfo();//控制台日志(列表);yieldput({type:'saveUserInfo',payload:list});}catch(e){console.error(e);}}},},};//user.jsx,业务组件文件import{connect}from'dva'classAppextendsComponent{componentDidMount(){//省略mapActionsToPops这一步this.props.dispatch({type:"用户/打开"})}}导出defaultconnect(//相当于mapStateToState,可以通过this.props.user(({user})=>{user}))(App)状态管理的最佳实践,应该推荐dva,再次感谢给前辈们开源的UI组件库,因为我平时不用UI库,所以可能会怀念。Ant-Design,pc版,制作后台管理系统的神器,也感谢前辈的开源。关键字,webpack按需加载,配置默认样式,使用babel-plugin-import(推荐)。//.babelrc或babel-loader选项{"plugins":["import",{"libraryName":"antd","libraryDirectory":"es","style":"css"//`style:true`会加载less文件}]]}然后直接从antd导入模块,不需要单独导入样式。相当于下面手动介绍的方式。//babel-plugin-import会帮你从'antd'加载JS和CSSimport{DatePicker};Ant-degsin-mobile关键字,按需加载,修改默认样式使用babel-plugin-import(推荐)。//.babelrc或babel-loader选项{"plugins":[["import",{libraryName:"antd-mobile",style:"css"}]//`style:true`将加载更少的文件]}然后只需从antd-mobile导入模块即可,无需单独导入样式。//babel-plugin-import会帮你从'antd-mobile'加载JS和CSSimport{DatePicker};React的AntDesignMobileRN在react-native中使用Ant-Designyarn在babel中添加@ant-design/react-native在配置中:"plugins":[["import",{libraryName:"@ant-design/react-native"}]]在React-native组件中使用:importReactfrom'react';import{View,Text,FlatList,SectionList,Alert}from'react-native';import{Button,Flex}from'@ant-design/react-native';导出默认类AppsextendsReact.Component{render(){return({Alert.alert(12312312);}}>12345561);}}Electron,PC端跨平台技术方案,集成Node,可以开发极其复杂的应用渲染进程和主进程使用remote模块或者ipc通信方式进行通信,然后可以完美调用原生接口解决macos、windows、linux三端统一开发。Electron框架结合了Chromium、Node.js和用户API,用于调用操作系统的原生功能(例如打开文件窗口、通知、图标等)基于Electron的开发就像开发网页一样,可以无缝使用Node.或者换句话说:在构建Node应用程序时,使用HTML和CSS构建界面。此外,您只需要为一个浏览器(最新的Chrome)设计(即无需担心兼容性等),远程}来自“电子”;ipcRenderer.removeAllListeners();ipcRenderer.on('loginSuccess',()=>{ipcRenderer.send('reply','loginSuccess');props.history.push('/login/loading');props.dispatch({type:'globalstate/saveStatus',payload:1});});这是一个很好的框架,考验一个前端工程师的底层技术,可能会写大量的底层Node。js和nativejavascript,目前很多IM项目都使用这个框架。github上的star数量快80K了。react-native,Mac是移动端跨平台框架跨平台开发的首选。没有关于构建完整原生环境的官方建议。不高,难度是适配和踩坑,遇到问题需要多百度。rn的生态也很强大,给我们封装了很多内容,还可以使用一些原生的接口。React-native层次结构:Java层:该层主要提供AndroidUI渲染器UIManager(将JavaScript映射到AndroidWidget)和其他一些功能组件(如Fresco、Okhttp)等,在java层被封装为模块。java层的核心jar包是react-native.jar,封装了很多上层接口,如Module、Registry、bridge等。C++层:主要处理Java和JavaScript的通信以及JavaScript代码的执行.这一层封装了JavaScriptCore,执行js的解析。基于JavaScriptCore,web开发者可以充分使用ES6的新特性,如类、箭头运算符等,而ReactNative运行在JavaScriptCore中,完全没有浏览器兼容性。Bridge桥接了java和js通信的核心接口。JSLoader主要是从assets目录或者本地文件加载javascriptCore,然后通过JSCExecutor解析js文件。js层:这一层为开发者提供各种组件和一些工具库。Component:js层通过js/jsx编写的VirtualDom构建Component或Module。VirtualDOM是DOM在内存中的一种轻量级表达,可以通过不同的渲染引擎生成不同平台下的UI。组件的使用在React中极其重要,因为组件的存在使得计算DOMdiff的效率更高。ReactReconciler:用于管理顶层组件或子组件的挂载、卸载和重绘。注:JSCore,JavaScriptCore,JS解析的核心部分,IOS使用内置的JavaScriptCore,Android使用来自https://webkit.org的jsc.so。启动过程分析:1.ReactInstanceManager在创建时会配置应用需要的java模块和js模块,通过ReactRootView的startReactApplication启动APP。2、创建ReactInstanceManager时,会创建加载JsBundle的JSBundlerLoader,传递给CatalystInstance。3.CatalystInstance会创建Java模块注册表和Javascript模块注册表,并遍历实例化的模块。4、CatalystInstance通过JSBundlerLoader向NodeServer请求JsBundle,传递给JSCJavaScriptExectutor,最后传递给javascriptCore,然后通过ReactBridge通知ReactRootView完成渲染。Js与Java的通信机制Java与Js的调用是建立在双方存在同一个模块配置表的基础上的。最后将call转化为{moduleID,methodID,callbackID,args},处理端查看模块配置表。注册模块和方法并调用它们。Java通过registry调用JsJava到CatalystInstance实例,通过ReactBridge的jni调用Onload.cpp中的callFunction,最后通过javascriptCore调用BatchedBridge.js,根据参数{moduleID,methodID}require执行对应的Js模块。流程如下图所示:Js调用Java。如果消息队列中有等待Java处理的逻辑,超过5msJava还没来拿走,那么JavaScript就会主动调用Java方法。当需要调用Java模块方法时,会传递参数{moduleID,methodID}等数据存放在MessageQueue中,等待Java事件触发,将MessageQueue中的{moduleID,methodID}返回给Java,然后根据模块注册表找到对应的模块进行处理。过程如下:参考文章,分析react-native的原理,看到react-native跨平台无缝对接js和react,所以决定坚定使用。希望在1.0版本到来的时候给我们一个惊喜。京东Taro多端解决方案Taro是一套遵循React语法规范的多端开发解决方案。现在市面上的终端形式多种多样,流行的有Web、React-Native、微信小程序等各种终端。当业务需求同时需要不同端的性能时,为不同端编写多套代码。成本显然非常高。这个时候,只用一套代码就可以适配多种终端的能力就显得极为必要了。使用Taro,我们可以只写一套代码,然后使用Taro的编译工具,将源码编译成不同终端(微信/百度/支付宝/字节跳动小程序、H5、React-Native等)的代码。代码示例:importTaro,{Component}from'@tarojs/taro'import{View,Button}from'@tarojs/components'exportdefaultclassIndexextendsComponent{constructor(){super(...arguments)this.state={title:'Home',list:[1,2,3]}}componentWillMount(){}componentDidMount(){}componentWillUpdate(nextProps,nextState){}componentDidUpdate(prevProps,prevState){}shouldComponentUpdate(nextProps,nextState))){returntrue}add=(e)=>{//dosth}render(){return({this.state.title}{this.state.list.map(item=>{return({item})})}Add)}}关键字,编译成不同平台应用并输出Taro有自己的脚手架。脚手架配置为什么要加入太郎?因为是国产的,而且是基于react的,应该会支持,相信以后应该会有很好的前景。环境搭建:首先需要使用npm或者yarn全局安装@tarojs/cli,或者直接使用npx:$yarnglobaladd@tarojs/cli使用命令创建模板工程$taroinitmyApp选择微信小程序模式,需要自己下载并打开微信开发者工具,选择项目根目录进行预览。微信小程序编译预览打包(去掉--watch不会监听文件修改,会压缩打包代码)#yarn$yarndev:weapp$yarnbuild:weapp#npmscript$npmrundev:weapp$npmrunbuild:weapp#仅全局安装$tarobuild--typeweapp--watch$tarobuild--typeweapp#npx用户也可以使用$npxtarobuild--typeweapp--watch$npxtarobuild--typeWeappH5模式,无需特定的开发者工具,执行如下命令后可通过浏览器预览#yarn$yarndev:h5#npmscript$npmrundev:h5#仅全局安装$tarobuild--typeh5--watch#npx用户即可也可以使用$npxtarobuild--typeh5--watchReactNative#yarn$yarndev:rn#npmscript$npmrundev:rn#仅全局安装$tarobuild--typern--watch#npx用户也可以使用$npxtarobuild--typern--watchTaro也有自己的生态系统,非常庞大。非常感谢京东的开源,希望它的功能越来越强大。最后总结:React本身很强大,生态系统也很强大。可以说任何平台上的大型应用都可以通过它来实现。hooks的出现,未来可期。用什么框架或技术来绘制UI并不重要,但我认为js和react的无缝衔接更倾向于与rn、taro、electron等框架开发跨平台应用。关于react的优化总结稍后放出,如果觉得写得好可以点个赞~谢谢