关于react.js:antd的Form表单的回显

最近刚开始用antd,回显网上搜了一圈,都不太清晰。所以保留一下我的用法。 1 利用initialValue render() { // @ts-ignore const {location} = this.props; const data = location.state; let responsiblePeoplePhone = {}; if(data){ responsiblePeoplePhone={initialValue:data.responsiblePeoplePhone||''}; } return( <FormItem {...formItemLayout} label="负责人联系方式" required={true} hasFeedback={true} name="responsiblePeoplePhone" {...responsiblePeoplePhone} rules={[ { required: true, message: '请填写负责人联系方式', }, { pattern: ValidConst.phone, message: '请输出正确的负责人联系方式', }, ]} > <Input /> </FormItem> )2 应用setFieldsValue render() { // @ts-ignore const {location} = this.props; const data = location.state; // ref form this.formRef.current.setFieldsValue({ responsiblePeoplePhone: data.responsiblePeoplePhone }) return( <FormItem {...formItemLayout} label="负责人联系方式" required={true} hasFeedback={true} name="responsiblePeoplePhone" rules={[ { required: true, message: '请填写负责人联系方式', }, { pattern: ValidConst.phone, message: '请输出正确的负责人联系方式', }, ]} > <Input /> </FormItem> ) getData() { 获取输出值 const fieldsValue = this.formRef.current.getFieldsValue(); let result = { responsiblePeoplePhone: fieldsValue.responsiblePeoplePhone , }; return result; }

May 25, 2021 · 1 min · jiezi

关于react.js:关于React的事件机制简单解释

对于React来说 它领有与原生js事件不同的一套事件机制 叫做合成事件(SyntheticEvent) const Text = ({list,handleClick}) => ({ list.map((item,index) => ( <span key={index} onClick= {clickHandle}>{item}</span>))})看到这段代码肯定是感觉这个点击事件是绑定在每一个标签上 但对于react来说却并不是,jsx语法写的事件并不是绑定在对应的实在DOM中,而是通过事件代理的形式,将所有的事件都对立绑在了document上,用这种形式的益处在于缩小了内存耗费,在组件挂载销毁时对立订阅与移除事件,性能优化了很多 在原生js当中的一些事件是对React不起作用的 比方阻止冒泡 如果咱们想要在一些状况下不想要冒泡事件,应用event.stopPropagation是有效的 应该应用event.preventDefault 另外与原生事件不同的一些区别:写法不同 合成事件是驼峰写法,而原生事件则是全副小写 <button onclick="clickHandle()"> test</button><button onClick="clickHandle()"> test</button>与原生js事件的执行程序 componentDidMount() { this.parent.addEventListener('click', (e) => { console.log('dom parent');})this.child.addEventListener('click', (e) => { console.log('dom child');})document.addEventListener('click', (e) => { console.log('document');})} childClick = (e) => { console.log('react child');} parentClick = (e) => { console.log('react parent');} render() { return ( <div onClick={this.parentClick} ref={ref => this.parent = ref}> <div onClick={this.childClick} ref={ref => this.child = ref}> test </div> </div>)} ...

May 24, 2021 · 1 min · jiezi

关于react.js:react-native-flatList的菊花引发的血案

背景下拉刷新上拉加载性能在挪动端无论是App还是小程序都是十分高频应用的组件,最近在开发RN的时候,本想着这个轮子应该很成熟了,于是跑遍了github都找不到一个自我感觉很完满的刷新组件,而且star数高的组件很多都是几年前保护的,说到这个,不得不吐槽一下,RN的生态在国内真的是太窄了,遇到略微小众一点的问题,国内某搜索引擎能找到答案的概率为50%,某歌的概率为80%,并且反复率十分高,始终认为RN会因为react的光环,社区应该会十分欠缺,后果令我悲观。挣扎了一番之后,决定还是用RN自带的组件--flatList,略微封装了一层,在Tab路由页应用没有问题,然而在详情页应用的时候,遇到了第一次加载和切换tab时,flatList刷新时候的indicator没有显示的bug,找遍了全网,只有国外友人遇到过,rn的issue也看到过,然而是18年左右的,被人关了,并且没有解决方案,惟一一个遇到跟我截然不同的人,他的解决方案是曲线救国,每次刷新的时候让列表滚回到顶部(因为indicator没有显示,其实是列表滚到底部把那个菊花给笼罩了),不能承受这种解决方案。 开发环境RN版本:0.64.0UI组件库:react native elements组件类型:函数式(hooks)导航版本(react native navigaton):5.X 尝试计划不管怎么设置list的高度也好,外层高度也好,写死高度和flex设置为1全都试过,全都没有### 背景下拉刷新上拉加载性能在挪动端无论是App还是小程序都是十分高频应用的组件,最近在开发RN的时候,本想着这个轮子应该很成熟了,于是跑遍了github都找不到一个自我感觉很完满的刷新组件,而且star数高的组件很多都是几年前保护的,说到这个,不得不吐槽一下,RN的生态在国内真的是太窄了,遇到略微小众一点的问题,国内某搜索引擎能找到答案的概率为50%,某歌的概率为80%,并且反复率十分高,始终认为RN会因为react的光环,社区应该会十分欠缺,后果令我悲观。挣扎了一番之后,决定还是用RN自带的组件--flatList,略微封装了一层,在Tab路由页应用没有问题,然而在详情页应用的时候,遇到了第一次加载和切换tab时,flatList刷新时候的indicator没有显示的bug,找遍了全网,只有国外友人遇到过,rn的issue也看到过,然而是18年左右的,被人关了,并且没有解决方案,惟一一个遇到跟我截然不同的人,他的解决方案是曲线救国,每次刷新的时候让列表滚回到顶部(因为indicator没有显示,其实是列表滚到底部把那个菊花给笼罩了),不能承受这种解决方案。 预期后果 理论后果 开发环境RN版本:0.64.0UI组件库:react native elements组件类型:函数式(hooks)导航版本(react native navigaton):5.X 尝试计划不管怎么设置list的高度也好,外层高度也好,写死高度和flex设置为1全都试过,全都没有用,然而我在设置refreshing为true的中央加了定时器,提早去刷新,就能失常显示菊花,所以我猜想是其余dom还没挂载渲染完,flatList就去刷新了,这个时候外层元素高度还没确定,所以列表滚到最底下,造成了菊花隐没的景象,然而useEffect会在组件渲染到屏幕之后执行,讲道理不应该会产生这种bug 解决方案在无数遍的调试下,我发现把react native elements组件库的Header组件移除后,第一次进入页面的菊花失常显示了,然而切换页面还是没有显示。因为我想让list组件在平安区域显示,所以我的flatList包裹了一层SafeAreaView,款式设置了flex:1,当我尝试把他移除后,应用View代替了它,当初后果如我预期显示。 父组件: <View style={common.container}> <ButtonGroup onPress={updateIndex} selectedIndex={selectedIndex} buttons={['文件', '流程核心']} containerStyle={styles.buttonGroup} textStyle={styles.buttonGroupText} /> {selectedIndex === 0 ? <ProjectFileList /> : <ProjectWorkflow />}</View>子组件: <View style={styles.container}> <SearchBar containerStyle={styles.searchBarContainer} inputStyle={styles.searchInput} inputContainerStyle={styles.searchInputContainer} lightTheme={true} placeholder="搜寻" /> <RefreshableList loadMore={loadMore} data={dataList} renderItem={renderItem} refreshing={refreshing} onRefresh={handleRefresh} onEndReached={handleLoadMore} keyExtractor={item => item.resId} /></View>自定义Header启用了react native elements的Header后,开始寻找代替的Header计划,最初还是决定用react native navigation提供的api实现。 screenOptions配置页面导航的默认参数配置导航的全局对立款式: <Stack.Navigator initialRouteName="Login" screenOptions={({ navigation }) => { return { headerStyle: { backgroundColor: colors.primary }, headerTitleStyle: { color: '#FFFF' }, headerBackTitleStyle: { color: '#FFFF' }, headerBackTitleVisible: false, headerBackImage: () => ( <TouchableOpacity onPress={navigation.goBack}> <Ionicons name="arrow-back" size={24} color={'#fff'} /> </TouchableOpacity> ), headerLeftContainerStyle: { paddingLeft: 10 }, headerRightContainerStyle: { paddingRight: 10 } }; }} > {// 页面的若干配置...}</Stack.Navigator>NavigationContainer能够承受一个theme参数,承受主题款式,在路由外面就能应用useTheme拿到全局款式。<NavigationContainer theme={MyTheme}> {// 若干配置...}</NavigationContainer>MyTheme.js ...

May 24, 2021 · 2 min · jiezi

关于react.js:react边界错误问题优化

了解:谬误边界(Error boundary):用来捕捉后辈组件谬误,渲染出备用页面 特点:只能捕捉后辈组件生命周期产生的谬误,不能捕捉本人组件产生的谬误和其余组件在合成事件、定时器中产生的谬误 应用形式:getDerivedStateFromError 配合 componentDidCatch // 生命周期函数,一旦后盾组件报错,就会触发static getDerivedStateFromError(error) { console.log(error); // 在render之前触发 // 返回新的state return { hasError: true, };}// 渲染组件出错,会调用这个生命周期函数componentDidCatch(error, info) { // 统计页面的谬误。发送申请到后盾去,配合后盾产生对应的谬误反馈机制,比方邮件或者短信告诉 console.log(error, info);}示例: export default class Parent extends Component { state = { hasError: '' //用于标识子组件是否产生谬误 } //当Parent的子组件呈现报错时候,会触发getDerivedStateFromError调用,并携带错误信息 static getDerivedStateFromError(error) { console.log('@@@', error) return { hasError: error } } componentDidCatch() { console.log('此处统计谬误,反馈给服务器,用于告诉编码人员进行bug的解决') } render() { return ( <div> <h2>我是Parent组件</h2> // 能够应用用户心理学办法,网络不稳固等揭示形式 {this.state.hasError ? <h2>以后网络不稳固,稍后再试</h2> : <Child />} </div> ) }}class Child extends Component { state = { users: [ { id: '001', name: 'tom', age: 18 }, { id: '002', name: 'jack', age: 19 }, { id: '003', name: 'peiqi', age: 20 } ] } render() { return ( <div> <h2>我是Child组件</h2> {this.state.users.map(userObj => { return ( <h4 key={userObj.id}> {userObj.name}----{userObj.age} </h4> ) })} </div> ) }}

May 23, 2021 · 1 min · jiezi

关于react.js:react类组件优化

Component的2个问题只有执行setState(),即便不扭转状态数据, 组件也会从新render() ==> 效率低只以后组件从新render(), 就会主动从新render子组件,纵使子组件没有用到父组件的任何数据 ==> 效率低效率高的做法只有当组件的state或props数据产生扭转时才从新render() 起因Component中的shouldComponentUpdate()总是返回true 解决方法1: 重写shouldComponentUpdate()办法 比拟新旧state或props数据, 如果有变动才返回true, 如果没有返回false方法2: 应用PureComponent PureComponent重写了shouldComponentUpdate(), 只有state或props数据有变动才返回true留神: 只是进行state和props数据的浅比拟, 如果只是数据对象外部数据变了, 返回false 不要间接批改state数据, 而是要产生新数据(对象或者数组的时候能够应用扩大运算符) 我的项目中个别应用PureComponent来优化示例: import React, { PureComponent } from 'react'import './index.css'export default class Parent extends PureComponent { state = { carName: '飞驰c36', stus: ['小张', '小李', '小王'] } addStu = () => { /* const {stus} = this.state stus.unshift('小刘') this.setState({stus}) */ const { stus } = this.state this.setState({ stus: ['小刘', ...stus] }) } changeCar = () => { //this.setState({carName:'迈巴赫'}) const obj = this.state obj.carName = '迈巴赫' console.log(obj === this.state) this.setState(obj) } /* shouldComponentUpdate(nextProps,nextState){ console.log(this.props,this.state); //目前的props和state console.log(nextProps,nextState); //接下要变动的指标props,指标state return !this.state.carName === nextState.carName } */ render() { console.log('Parent---render') const { carName } = this.state return ( <div className="parent"> <h3>我是Parent组件</h3> {this.state.stus}&nbsp; <span>我的车名字是:{carName}</span> <br /> <button onClick={this.changeCar}>点我换车</button> <button onClick={this.addStu}>增加一个小刘</button> <Child carName="奥拓" /> </div> ) }}class Child extends PureComponent { /* shouldComponentUpdate(nextProps,nextState){ console.log(this.props,this.state); //目前的props和state console.log(nextProps,nextState); //接下要变动的指标props,指标state return !this.props.carName === nextProps.carName } */ render() { console.log('Child---render') return ( <div className="child"> <h3>我是Child组件</h3> <span>我接到的车是:{this.props.carName}</span> </div> ) }}

May 23, 2021 · 1 min · jiezi

关于react.js:React将页面部分内容做成子组件

背景介绍实验室开发的一套课程实际平台,用于老师学生日常应用。负责一个小局部,将一个显示性能做成一个子组件即可。页面该当正确显示图示属性。 问题形容及剖析一、第一次通过npm install想把我的项目跑起来时,呈现以下谬误。提醒npm版本太老,于是试图更新npm,也提醒更新失败,这时通过npm -v查看npm版本时又呈现以下谬误,阐明npm曾经被毁坏。于是卸载node.js重新安装,这时node -v可显示进去版本,然而npm -v仍旧是上述谬误。起初通过网络查问,删掉了文件中的npm npm-cache两个文件,重新安装node.js,运行npm -v,即失去正确后果。二、后缀jsx和js less和css结尾文件区别看到代码中有些文件是以jsx less为后缀的,然而内容和JS CSS代码差不多一样,于是查找了他们之间的区别。 1.js,是一种直译式脚本语言2.jsx,JavaScript XML是一种在React组件外部构建标签的类XML语 法。less和Sass都是CSS延长出的语言。目标是为了不便前端开发,缩小工作量。LESS保留了css的任何性能,同时提供了多种形式能平滑的将写好的代码转化成规范的CSS代码,能够在任何时候随时切换到css的语法进行书写。 三、React.Component与React.PureComponent的区别 (React.PureComponent 与 React.Component 简直完全相同,但 React.PureComponent 通过prop和state的浅比照来实现 shouldComponentUpate()。 如果React组件的 render() 函数在给定雷同的props和state下渲染为雷同的后果,在某些场景下你能够应用 React.PureComponent 来晋升性能。React.PureComponent 的 shouldComponentUpdate() 只会对对象进行浅比照。 React.PureComponent能够实现在state,props不变的状况下防止组件的反复渲染问题,当然它并不是万能的,它不能像shouldComponentUpdate实现本人定制化。 四、谬误显示,试图间接在子组件取得相干数据,呈现谬误无奈解决。起初,间接在父组件事后取得属性放进一个对象,间接将对象传给子组件可正确显示。 const reserachData = { moduleBelong: moduleInfomation, createTime: detailData.createTime, precondition: detailData.precondition, expectedStep: detailData.expectedStep, expectedResult: detailData.expectedResult, } return ( <> <ReserachForm reserachData={reserachData} />)五、React子组件反复渲染。 渲染函数的执行有两个毛病: - React 必须在每个组件上运行其差别算法,以查看是否应更新 UI。- 这些渲染函数或函数组件中的所有代码将再次执行。每当组件状态扭转时,React 都会调度渲染。可通过以下两种形式对代码进行优化 空间何时更新组件优化组件构造六、将代码push到gitee呈现以下问题。 将gitee注册时填写的邮箱地址改为公开,push胜利。 参考文档jsx和js后缀的区别十分钟看懂Css、less和Sass(SCSS)的区别React从渲染原理到性能优化(一) react 反复渲染react组件什么时候会从新渲染?

May 19, 2021 · 1 min · jiezi

关于react.js:react中使用keepAlive实现导航tabs

在后盾我的项目中应用tabs导航是一个重要的性能 上面介绍一下如果配合umi框架和对应的插件实现此性能 参考:react-activation 参考实现:实现一个tabs 目前我的项目用的架构设计是umi3+react17+antd pro5 1.引入应用相干插件 插件地址: umi-plugin-keep-alive npm install umi-plugin-keep-alive --save# oryarn add umi-plugin-keep-alive2.公共组件封装components文件夹下创立KeepAvlieTabs对应的less款式请自行批改本人的需要 相干的keepAlive与生命周期应用计划及问题请到上述链接react-activation查看创立index.tsx文件 // /components/KeepAvlieTabs/index.tsximport { useAliveController } from 'react-activation';import { arrayDeduplicate } from '@/utils/Array';import type { CachingNode } from './type';import Tab from './Tab';import styles from './index.less';import { useHistory, useLocation } from 'umi';export default function KeepAliveTabs() { // history导航 const history = useHistory(); // 本地路由信息 const location = useLocation(); // 获取缓存节点办法和信息 const { getCachingNodes } = useAliveController(); const cachingNodes: CachingNode[] = getCachingNodes(); // 因为是异步组件,须要在这儿解决一下缓存中的反复问题 let nodes: CachingNode[] = arrayDeduplicate(cachingNodes, 'path'); // 首页不参加tabs切换的敞开操作 nodes = nodes.filter((item) => item.path !== '/home'); return ( <ul className={styles['alive-tabs']}> <li className={location.pathname === '/home' ? styles.home_active : styles.home_deactive} onClick={() => { history.push('/home'); }} > <div className="tags-nav"> <span>首页</span> </div> </li> {nodes.map((node) => ( <Tab key={node!.id} node={node} /> ))} </ul> );}创立Tab.tsx文件 ...

May 17, 2021 · 3 min · jiezi

关于react.js:React-获取key-失败

问题在组件中获取 this.props.key 将失去 undefined。 起因大部分 JSX 元素上的 props 都会被传入组件,然而有两个非凡的 props (ref 和 key) 曾经被 React 所应用,不会被传入组件。 解决方案用一个不同的 prop 传入 <ListItem key={result.id} id={result.id} />。尽管这仿佛是多余的,然而将利用程序逻辑和协调提醒(reconciliation hints)离开是很重要的。

May 14, 2021 · 1 min · jiezi

关于react.js:React的plume2使用

Hello, plume2.import React, { Component } from 'react'import {Actor,Store,StoreProvider,Relax,ViewAction} from 'plume2'//MapReduce class HelloActor extends Actor{ defaultState(){ return {text:"Hello,plume2"} }}//reactive ui event 反应式ui事件class AppViewAction extends ViewAction{ sayHello = (text:any) =>{ this.store.dispatch('say:hello',text) }}// Single Data Source 繁多数据源class AppStore extends Store{ //bind data transform 绑定数据转换 bindActor(){ //after plume2 directly pass Actor class 间接通过Actor类 return [HelloActor] } //bind ui event 绑定ui事件 bindViewAction(){ return { AppViewAction } }}//Auto compute relaxProps 主动计算关上Props@Relax class Text extends React.Component{ static relaxProps = { //auto injected by store.state().get('text') 由store.state().get('text')主动注入 text:"text", //auto injected by store's bindViewAction 由store的bindViewAction主动注入 ViewAction:'viewAction' } _handleClick = () =>{ const {text,viewAction} = this.props.relaxProps viewAction.AppViewAction.sayHello(text) } render(){ const {text,viewAction} = this.props.relaxProps; return ( <div onClick={this._handleClick}>{text}</div> ) }}@StoreProvider(AppStore) //应用程序入口export default class Index extends Component { render() { return ( <div> <Text/> </div> ) }} ...

May 12, 2021 · 3 min · jiezi

关于react.js:ReactJS-Environment-Setup

In this chapter, we will show you how to set up an environment for successful React development. Notice that there are many steps involved but this will help speed up the development process later. We will need NodeJS, so if you don't have it installed, check the link from the following table. Sr.No.Software & Description1NodeJS and NPM NodeJS is the platform needed for the ReactJS development. Checkout our NodeJS Environment Setup. ...

May 12, 2021 · 6 min · jiezi

关于react.js:技术干货|7个-React-性能提升技巧

前言React 是由 Facebook 团队主导开发的UI框架,作为以后三大前端框架(另外两个是 Angular、Vue )之一,提供了数据驱动的 UI 开发模式,以及组件化的开发方式,能够构建高性能的前端利用。拍乐云音视频 PaaS 云平台为用户提供了 Console 控制台,控制台提供了利用治理、用量查看、费用治理、数据罗盘、用户治理等性能。控制台前端的开发抉择了 React 作为根底框架。在应用 React 过程中,咱们总结了 React 性能晋升的7个技巧,在这里和你分享。 熟记 Diffing 规定 1.当节点(包含 DOM 节点和组件节点)的类型发生变化时,React 会卸载该节点(蕴含子节点)的 DOM 树,而后从新渲染新的 DOM 树。 2.当 DOM 节点的类型不变时,React 会保留 DOM 节点,而后比照属性变动更新 DOM 节点。3.当组件节点的类型不变时,组件实例会放弃不变,比照 props 属性而后更新组件。4.下面过程从根节点开始,递归到所有的叶子节点完结。从下面的规定咱们能够看出,组件是配角,前面的性能晋升点也是围绕组件的。从下面的规定能够看出大变动应该应用不同的组件,小变动应该批改属性。记住了 Diffing 规定其实就能够写出性能不错的 React 代码。下面只是一个总结,不须要能够具体看看这遍文档协调。 key 更新时 React 须要比照更新前后的变动,生成一个 mutation。没有 key,不能复用之前的组件,影响性能。 用数组索引来作为 key,因为是基于索引来决定组件的更新和复用,程序变动时会导致非受控组件变动达不到预期,比方冀望第一个元素和第二个元素对调地位,因为数组索引作为 key,非受控组件是复用的(前面有个性能晋升技巧就是应用非受控组件),React 辨认不进去地位变动,这里有个例子演示了索引作为 key 导致的问题。 最佳实际是在列表层应用惟一值作为 key,例如 id。 正当地拆分组件 咱们晓得 React 提供了组件式开发方式。写好 React 代码的根底就是组件拆分,正当地组件拆分既能够晋升的代码可维护性和可复用性,联合前面的性能技巧,还能够晋升性能。 1.组件拆分一个重要的准则是高内聚低耦合,子组件应该是一个独立的单元,子组件与父亲组件间的通信信息要少,数据申请应该放到子组件中,除非父组件也要应用。 function Page(props) => { return <Card> <MeetingInfo id={props.match.params.id} /> <UserList /></Card>;}function MeetingInfo(props) { ...

May 11, 2021 · 2 min · jiezi

关于react.js:React官网总结

外围概念: Babel会把JSX本义成一个React.createElement() 函数调用。理论代码:const element = ( <h1 className="greeting"> Hello, world! </h1>);React.createElement() 会事后执行一些查看,实际上是创立了一个对象。 const element = { type: 'h1', props: { className: 'greeting', children: 'Hello, world!' }};这些对象被称为React元素。元素是形成React的最小砖块。元素是一个对象。 如何将React元素渲染成DOM?想要将一个 React 元素渲染到根 DOM 节点中,只需把它们一起传入 ReactDOM.render()const element = <h1>Hello, world</h1>;ReactDOM.render(element, document.getElementById('root'));如何更新已渲染的DOM?React元素是一个不可变的对象。就相当于是电影中的每一帧对应的都是不同的UI。所以依照咱们之前将React元素渲染成DOM的办法,咱们只有把新的React元素渲染到DOM节点中,传入ReactDOM.render()React只更新它须要更新的局部ReactDOM 会将元素和以及子元素和它之前的状态比照。组件和props5.1 组件相当于是UI的拆分,为了实现复用。就相当于一个函数,通过props(相当于参数)灌入数据,通过state维持本身状态。返回React元素。5.2 props是只读的。引入一个概念——纯函数 函数外部不会批改入参,并且屡次传入雷同入参返回的后果都是一样的。state和生命周期 state是外部状态 是公有的 正确应用state: 6.1 不要间接批改state 6.2 state的更新是异步的 解决: 给state传入一个函数,还能够传一个回调函数 this.setState((state, props) => ({counter: state.counter + props.increment}));6.3 state更新会被合并的 数据是向下流动的列表和keykey 帮忙 React 辨认哪些元素扭转了,比方被增加或删除。因而你该当给数组中的每一个元素赋予一个确定的标识。key须要在兄弟节点间是惟一的。而不是全局。通常咱们应用id来作为key,用索引来做key不太好。而且key的设定通常是数组最近的上下文。一个经验之谈就是在map数组的时候设置key表单提一个概念,受控组件:向表单那样,数据源是react的state提供,每次输出过程中发送的操作也是react管制。输出的值始终由 React 的 state 驱动。例如:<form onSubmit={this.handleSubmit}> <label> 名字: <input type="text" value={this.state.value} onChange={this.handleChange} /> </label> <input type="submit" value="提交" /></form>生命周期 之前的版本挂载constructorrendercomponentDidMount更新componentWillReceivePropsshouldComponentUpdatacomponentWillUpdatarendercomponentDidUpdata卸载componentWillUnmount

May 11, 2021 · 1 min · jiezi

关于react.js:分享一个基于webpack5-react-antd的空后台优化的不错拿来即用

这是一个空的 react + antd 空治理后盾,只须要开发页面就能让它成为你想要的管理系统 线上地址:https://vibing.github.io/reac... 我的项目地址:https://github.com/Vibing/rea... 欢送 Star 和提供更好的倡议 概述该治理后盾基于 webpack5、 react@17、react-router@5.2、typescript、antd@4.10状态治理应用 mobx@6.x,相比 redux 应用更简略,整个我的项目应用多 store 进行状态治理更容易保护反对页面刷新后菜单和面包屑主动聚焦应用 dayjs 代替 momentjs反对 Code Splitting(代码宰割)、Optional Chaining(可选链)、Nullish Coalescing Operator(管制合并运算符)应用 DLL 提取公共库进行缓存 进步我的项目加载速度应用 Tree Shaking 优化我的项目,打包时删除没用到的代码antd 组件库按需引入我的项目构造.├── dll // 生成的DLL├── node_modules├── src ├── components // 专用组件 ├── pages // 用于寄存所有页面 ├── store // 顶级store,我的项目内任何中央都能拜访 ├── public ├── App.tsx // APP组件 ├── routes.ts // 路由 ├── index.tsx // 整个我的项目的入口 └── index.ejs // 模板├── tsconfig.json // typescript配置├── typings // 自定义类型├── webpack├── package.json└── yarn.lock应用- git clone https://github.com/Vibing/react-admin.git- cd react-admin && yarn- yarn dll- yarn dev执行下面命令后 关上 http://localhost:3000/#/home 即可拜访 ...

May 10, 2021 · 2 min · jiezi

关于react.js:react-hook下的hoc组件

假如咱们有组件login和组件user,login组件外部有用户名明码输出,而后发送ajax申请给后端,后端返回胜利,同时把用户list信息也返回了,而后间接把list当参数传给user组件。同时也显示user组件。大略的调用形式就是 <Login> <User /></Login>interface ILoginProps { children: React.ReactElement;}const Login: FC<ILoginProps> = (props) => { const getChildNode = () => { if (props?.children) { const cloned: React.ReactElement = React.cloneElement(props?.children, { initImInfo, initConfInfo, initUserInfo, isHost }); return cloned; } return <div />; }; return {isLoginSuccess ?getChildNode(): <LoginFrom>}})React.cloneElement的应用,它的第二个参数就是传给child的props.

May 10, 2021 · 1 min · jiezi

关于react.js:在nextjs中捣腾一下暗黑主题

不能不说,写这个的时候,真的好饿! 形容:在nextjs中对antd的亮白和暗黑主题切换实际。在线预览:https://zhoubangfu.com/demo/theme 18:00-7:00是暗黑主题,能够通过Redux DevTools提交action, {type: 'change_theme',value: 'dark/light'}来切换,或者在预览页面的下拉菜单切换也能够。代码仓库:https://github.com/zhoubangfu/nextjs-start预览图 次要用到一个webpack插件antd-theme-webpack-plugin。上面会一步一步的造~ 这个插件是基于应用webpack环境的,临时没有去看有没有大佬有开发反对vite的插件。在反对服务端渲染的我的项目中有了实际,那么在单页利用客户端渲染的我的项目中,就大同小异了。搭建我的项目其中增加redux、舍弃nextjs本身的css应用withCss插件、增加less\sass以及反对模块款式的内容就不谈了,内容很简略,能够间接看代码。 增加主题依赖yarn add -D antd-theme-webpack-plugin配置项1.增加自定义的主题 向styles文件夹中增加vars.less,内容能够像上面: // This file will contain all varibales, our custom varibales and//those from Ant Design which we want to override.@import '~antd/lib/style/themes/default.less';@primary-color: @green-6;@select-item-selected-option-color: @primary-color;@processing-color: @primary-color;@select-item-selected-bg: @background-color-base;@secondary-color: @primary-color;@skeleton-color: @primary-color;@btn-primary-bg: @primary-color;:root { --PC: @primary-color;}此内容来自nextjs的demo2.增加next配置 next.config.js const AntDesignThemePlugin = require('antd-theme-webpack-plugin');// antd-theme-generator插件在下面的依赖我的项目中有,所以不须要装置const { getLessVars } = require('antd-theme-generator');// 这一步是读取咱们预设的次要的主题变量(是不反对热更新的)const themeVariables = getLessVars(path.join(__dirname, './src/styles/vars.less'));// 读取暗黑主题const darkVars = { ...getLessVars('./node_modules/antd/lib/style/themes/dark.less'), '@picker-basic-cell-active-with-range-color': 'darken(@primary-color, 20%)'};// 亮白主题const lightVars = { ...getLessVars('./node_modules/antd/lib/style/themes/compact.less')};// 这一步即便启动或构建我的项目时生成对应的主题文件,用于我的项目中import// 最好的gitignore该生成的文件,每次主动生成fs.writeFileSync('./src/config/dark.json', JSON.stringify(darkVars));fs.writeFileSync('./src/config/light.json', JSON.stringify(lightVars));fs.writeFileSync('./src/config/theme.json', JSON.stringify(themeVariables));// 这里就是theme插件的配置项了const themeOptions = { stylesDir: path.join(__dirname, './src'), antDir: path.join(__dirname, './node_modules/antd'), varFile: path.join(__dirname, './src/styles/vars.less'), themeVariables: Array.from( new Set([ ...Object.keys(darkVars), ...Object.keys(lightVars), ...Object.keys(themeVariables) ]) ), indexFileName: false, // 这里须要将生成的less文件放到一个生产环境可能间接通过link获取的中央,所以这里放到public下 outputFilePath: path.join(__dirname, './public/color.less'), generateOnce: false};module.exports = withPlugins([withLess], { lessLoaderOptions: { javascriptEnabled: true, importLoaders: 1 }, webpack: (config, options) => { // 增加主题切换webpack插件 config.plugins.push(new AntDesignThemePlugin(themeOptions)); }}这部分即便最次要的配置内容,前面将开始应用该配置生成的内容了 ...

May 10, 2021 · 2 min · jiezi

关于react.js:ReactHooks-面试解答

最近看到一个对于 React 的面试题,是京东技术三面的题目,感觉很有意思,一起来看看: React 退出 Hooks 的意义是什么?或者说一下为什么 React 要退出Hooks 这一个性?最初举例说一下 Hooks 的根本实现原理; 首先,咱们看一下典型的两个 Hooks 的根本应用,间接看代码,这里就不细说了; useState 根本应用: // 引入 useStateimport React, { useState } from 'react'function App() { // 应用 const [count, setCount] = useState(1); return ( <div> <h2> useState </h2> <p>{count}</p> {/* 调用 setCount办法 */} <button onClick={() => setCount(count + 1)}> 加1 </button> </div> )}export default AppuseEffect : import React, { useState, useEffect } from 'react'import ReactDom from 'react-dom'function App() { const [count, setCount] = useState(1) // 组件挂载实现之后执行 && 组件数据更新实现之后执行 // useEffect(() => { // console.log('666') // }) // 组件挂载实现之后执行 // useEffect(()=>{ // console.log(678) // },[]) // 组件被卸载之前执行 (引入react-dom进行卸载测试) useEffect(()=>{ return ()=>{ console.log('组件被卸载了') } }) return ( <div> <h2>useEffect</h2> <p>{count}</p> <button onClick={() => setCount(count + 1)}> 加1 </button> {/* 卸载组件 */} <button onClick={()=>ReactDom.unmountComponentAtNode(document.getElementById('root'))}>卸载组件</button> </div> )}export default App回到后面的问题,其实这样的问题并没有什么标准答案,然而咱们能够换位思考,站在面试官的角度想一下,为什么会问这样的问题?无非就是想考查咱们对 Hooks 最根本的应用状况以及对 Hooks 设计理念的集体思考;其实在 React 官网文档中,曾经给出了答案,奈何很多人就是不看文档啊;Hook 简介 – React (docschina.org) ...

May 6, 2021 · 2 min · jiezi

关于react.js:React-Native-全方位异常监控

最近在做 RN 利用线上谬误监控的需要,在此记录下罕用计划。首发地址0. 开始React Native 在架构上整体可分为三块:Native、JavaScript 和 Bridge。其中,Native 治理 UI 更新及交互,JavaScript 调用 Native 能力实现业务性能,Bridge 负责在二者之间传递音讯。 最上层提供类 React 反对,运行在 JavaScriptCore 提供的 JavaScript 运行时环境中,Bridge 层将 JavaScript 与 Native 世界连接起来。 本文从以下三个角度,别离介绍如何捕捉 RN 利用中未被解决的异样: Native 异样捕捉;JS 异样捕捉;React 异样捕捉;1. Native 异样捕捉Native 有较多成熟的计划,如友盟、Bugly、网易云捕和 crashlytics 等,这些平台不仅提供异样捕捉能力,还相应的有上报、统计、预警等能力。本文不对以上平台异样捕捉实现形式进行剖析,而是通过剖析 react-native-exception-handler 理解 Native 端异样捕捉的实现原理。 react-native-exception-handler 实现了 setNativeExceptionHandle 用于设置 Native 监测到异样时的回调函数,如下所示: export const setNativeExceptionHandler = (customErrorHandler = noop, forceApplicationToQuit = true, executeDefaultHandler = false) => { if (typeof customErrorHandler !== "function" || typeof forceApplicationToQuit !== "boolean") { console.log("setNativeExceptionHandler is called with wrong argument types.. first argument should be callback function and second argument is optional should be a boolean"); console.log("Not setting the native handler .. please fix setNativeExceptionHandler call"); return; } if (Platform.OS === "ios") { ReactNativeExceptionHandler.setHandlerforNativeException(executeDefaultHandler, customErrorHandler); } else { ReactNativeExceptionHandler.setHandlerforNativeException(executeDefaultHandler, forceApplicationToQuit, customErrorHandler); }};1.1 Android 异样捕捉Android 提供了一个异样捕捉接口 Thread.UncaughtExceptionHandler 用于捕捉未被解决的异样。react-native-exception-handler 亦是基于此实现对 Android 端异样捕捉的,其次要代码及剖析如下所示: ...

April 29, 2021 · 7 min · jiezi

关于react.js:react的hooks教程

这是一篇react的hooks教程另外欢送大家拜访我的博客 react hooks 与 class Component 的区别写法更加简洁,不再须要写简短的生命周期函数class Componet hoc 的浏览让人看起来不易了解, 在组件之间复用状态逻辑很难.hooks 应用规定只能在函数最外层调用 Hook。不要在循环、条件判断或者子函数中调用。只能在React的函数组件中调用Hook。不要在其余JavaScript函数中调用。除了自定义的hook以外react hooks 常见的api应用useState 用法identity: const [state, setState] = useState(initialState)useState的作用是在react函数组件中增加state的hook。 import React, { useState } from 'react'; function Count() { /* - count <=> this.state.count, setCount <=> this.setState - setCount 反对两种写法 setCount(count + 1) or setCount(preState => preState + 1) 第一种写法是一种异步机制,会将短时间内的多个setCount合并成一个办法,第二种写法是为了不应用第一种的合并机制。 */ const [count, setCount] = useState(0); return <div onClick={setCount(pre => pre + 1)}>{count}</div> }useEffect 用法identity: useEffect(callBack:clearCallBack, [deps])useEffect的作用是在函数组件中执行副作用操作, 等价于在ComponetDidMount,ComponentDidUpdate, ComponentWillUnmount 三个函数的组合。 ...

April 24, 2021 · 4 min · jiezi

关于react.js:浅入深知React

React.creatElement 创立虚构dom 对于虚构DOM: 实质是Object类型的对象 (个别对象)虚构DOM比拟轻 实在DOM比拟重 因为虚构DOM是React外部应用 无需实在DOM上那么多属性虚构DOM最终会被React转化为实在DOM 出现在页面上jsx的语法规定 1.定义虚构Dom时不要写引号2 标签中混入js表达式时用{}3 款式的类名指定不要用class 要用className4 内联款式 要用style={{key:value}}的模式去写4 只有一个根标签6 标签必须闭合7 标签首字母 1 若小写字母结尾 则将标签转为html 中的同名元素 ,若html中无该标签对应的同名元素 则报错。 2 若大写字母结尾 react 就去渲染对应的组件 若组件没有定义 则报错js语句(代码)与js表达式 1 表达式:一个表达式会产生一个值 能够放在任何一个须要值的中央 上面这些都是表达式: 1 a 2 a+b 3 demo(1) 4 arr.map() 5 function test(){}2 语句(代码) 上面这些都是语句(代码) 1 if(){} 2 for(){} 3 switch(){}React中的ref字符串的ref回调模式的ref class GetValue extendsReact.Component{ getValue = () =>{ let {input1} = this console.log(input1.value); } changeHot= ()=>{ let {isHot} = this.state this.setState({ isHot:!isHot }) } state = { isHot:false } refInput1=(c)=>{ this.input1 = c } render(){ console.log(this); let {isHot} = this.state return( <div> <h1>今天天气{isHot?'晴朗':'阴天'}</h1> <button onClick={this.changeHot}>扭转天气</button> <input ref={this.refInput1} type="text"/>&nbsp; <button onClick={this.getValue}>获取Input1的value</button> </div> ) } } ReactDOM.render(<GetValue/>,document.getElementById('test'))createRef的ref ...

April 20, 2021 · 1 min · jiezi

关于react.js:从零到一搭建React组件库

最近始终在捣鼓如何搭建React组件库,至于为什么会产生这个想法,次要是因为组件库对于前端生态来说究极重要,每一个着眼于久远倒退、看重开发效率的的互联网公司基本上都会量身定制本人的组件库,它的益处不必多说。对于前端工程师而言,去了解以及把握它,能够让咱们在今后的工作中以及应聘过程中多出一项非凡技能,并且对本身的纵向倒退也就是很无利的。上面是我记录我在搭建组件库的过程。 初始化工程搭建工程不打算采纳create-react-app脚手架来搭建,因为脚手架封装好了很多货色,而有些货色对于组件库并不实用,用来搭建组件库过于臃肿,因而我不打算借助任何脚手架来搭建工程。 首先,先创立一个工程文件夹pony-react-ui,在该文件夹下执行如下命令: npm init // 生成package.jsontsc --init // 生成tsconfig.json而后,依照如下目录构造初始化工程: pony-react-ui├── src ├── assets ├── components ├── Button ├── Button.tsx └── index.ts └── Dialog ├── Dialog.tsx └── index.ts ├── styles ├── _button.scss ├── _dialog.scss ├── _mixins.scss ├── _variables.scss └── pony.scss └── index.ts // 打包的入口文件,引入pony.scss,抛出每一个组件├── index.js // 入口文件,package.json中main字段指定的文件├── package.json├── tsconfig.json├── webpack.config.js└── README.md编写一个Button组件Button组件应该满足一下需要: 不同尺寸不同类型不同色彩禁用状态点击事件Button.tsx import React from 'react';import classNames from 'classnames';export interface IButtonProps { onClick?: React.MouseEventHandler; // 类型 primary?: boolean; secondary?: boolean; outline?: boolean; dashed?: boolean; link?: boolean; text?: boolean; // 尺寸 xLarge?: boolean; large?: boolean; small?: boolean; xSmall?: boolean; xxSmall?: boolean; // 色彩 success?: boolean; warn?: boolean; danger?: boolean; // 禁用状态 disabled?: boolean; className?: string; style?: React.CSSProperties; children?: React.ReactNode;}export const Button = (props: IButtonProps) => { const { className: tempClassName, style, onClick, children, primary, secondary, outline, dashed, link, text, xLarge, large, small, xSmall, xxSmall, success, danger, warn, disabled, } = props; const className = classNames( { 'pony-button': true, 'pony-button-primary': primary, 'pony-button-secondary': secondary && !text, 'pony-button-outline': outline, 'pony-button-dashed': dashed, 'pony-button-link': link, 'pony-button-text': text && !secondary, 'pony-button-text-secondary': secondary && text, 'pony-button-round': round, 'pony-button-rectangle': noRadius, 'pony-button-fat': fat, 'pony-button-xl': xLarge, 'pony-button-lg': large, 'pony-button-sm': small, 'pony-button-xs': xSmall, 'pony-button-xxs': xxSmall, 'pony-button-long': long, 'pony-button-short': short, 'pony-button-success': success, 'pony-button-warn': warn, 'pony-button-danger': danger, 'pony-button-disabled': disabled, }, tempClassName ); return ( <button type="button" className={className} style={style} onClick={onClick} disabled={disabled}> <span className="pony-button__content">{children}</span> </button> );}在Button/index.ts文件中抛出Button组件以及定义的类型 ...

April 19, 2021 · 2 min · jiezi

关于react-hooks:React-Hook介绍和应用

介绍:官网上,给Hook的定义是:一些能够让你在函数组件里“钩入” React state 及生命周期等个性的函数。Hook不能在class中应用,然而,能够在新组件中应用Hook。 Hook的应用规定:1,只能在函数最外层调用Hook,不要在循环,条件判断 或 子函数 中调用Hook2,只能在两个中央调用Hook,React 的函数组件 和 自定义Hook中 自定义Hook:如果函数的名字以 “use” 结尾并调用其余 Hook,咱们就说这是一个自定义 Hook应用场景:组件之间重用一些状态逻辑。 特点:自定义Hook 的每次调用都有一个齐全独立的 state —— 因而你能够在单个组件中屡次调用同一个自定义 Hook。 内置的几个HookuseState入参:定义的state中变量的初始值返回值:定义的state中变量名; 批改此变量的办法, 更新此变量时,总是替换它,而不是合并它(和this.setState( ) 区别的合并不同,留神区别)例1: // 申明一个count的state变量,它的初始值是0,并且通过setCount办法更新countconst [count, setCount] = useState(0);例2: // 可在一个react组件中定义多个useStateconst MultiThing = () => { const [age, setAge] = useState(30) const [] = useState('apple') // error变量是Error或者null类型,并且初始值是null const [error, setError] = useState<Error | null>(null);}接下来几天,会持续介绍其余Hook和我的项目中用到的自定义Hook

April 18, 2021 · 1 min · jiezi

关于react.js:react

转自React技术揭秘 React15React15架构能够分为2层: Reconciler(协调器)————负责找出变动的组件,diffRenderer(渲染器)————负责将变动的组件渲染到页面上Reconciler(协调器)react是通过this.setState,this.forceUpdate,ReactDOM.render等API触发更新的。每当有更新产生时,Reconciler会做如下工作: 调用函数组件、或class组件的render办法,将返回的JSX转化为虚构DOM将虚构DOM和上次更时的虚构DOM比照通过比照找出本次更新中变动的虚构DOM告诉Renderer将变动的虚构DOM渲染到页面上 Renderer(渲染器)因为react反对跨平台,所以不同平台有不同的Renderer,浏览器的是ReactDOM因为用递归执行,所以没方法中断,当层级很深时,递归更新工夫超过了16ms,用户交互就会卡顿 state=1;<li>{state.count}</li>//<li>1</li><li>{state.count*2}</li>//<li>2</li>当点一个state+1时更新步骤: Reconciler发现1须要变为2,告诉Renderer,Renderer更新DOM,1变为2。Reconciler发现2须要变为4,告诉Renderer,Renderer更新DOM,2变为4。能够看到,Reconciler和Renderer是交替工作的,当第一个li在页面上曾经变动后。第二个li才进入Reconciler。就是发现扭转渲染扭转,扭转就渲染的模式 React16react16的架构能够分为三层: Scheduler(调度器)————调度工作的优先级,高优工作优先进入ReconcilerReconciler(协调器)————负责找出变动的组件,diff,又被称为render阶段,在此阶段会调用组件的render办法。Renderer(渲染器)————负责将变动的组件渲染到页面上,又被称为commit阶段,就像git commit一样把render阶段的信息提交渲染到页面上。render与commit阶段统称为work。 Scheduler(调度器)以浏览器是否有剩余时间作为工作中断的规范,也须要当浏览器有剩余时间时来告诉到咱们,相似API:requistIdCallback。就是判断浏览器有无剩余时间,如有按优先级继续执行Reconciler Reconciler(协调器)在react15是用递归来解决虚构DOM,react16的更新工作从递归变成能够中断的循环过程。 /** @noinline */function workLoopConcurrent() { // Perform work until Scheduler asks us to yield while (workInProgress !== null && !shouldYield()) { workInProgress = performUnitOfWork(workInProgress); }}在React16中,Reconciler和Renderer不是交替工作,而是当Scheduler将工作交给Reconciler后,Reconciler会将变动的虚构DOM打上增/删/改的tag。整个Scheduler与Reconciler的工作都在内存中进行,只有当所有组件都实现Reconciler的工作,才会对立交给Renderer渲染 Renderer(渲染器)Renderer依据Reconciler为虚构DOM打的标记,同步执行对应的DOM操作。 state=1;<li>{state.count}</li>//<li>1</li><li>{state.count*2}</li>//<li>2<li>当点一个state+1时更新步骤: Scheduler接管到更新,看下有没有其它高优先更新要执行,没有的放将state.count从1变成2,交给Reconciler。Reconciler接管到更新,找出须要变动的虚构DOM,发现在1要变成2打tag:Update,又发现了2要变成4再给第二个打上tag:Update。都完了之后将打了标识的虚构DOM给Renderer。Renderer接管到告诉,找到打了Update标识的2个虚构DOM,对它们执行更新DOM的操作。2,3步可随时因为有其它高优先级工作先更新或没有剩余时间而中断,但因为2,3都是在内存中进行,不会更新页面上的DOM,所以就算重复中断,用记也不会看到更新一半的DOM Fiber在react15及之前,Reconciler采纳递归的形式创立虚构DOM,递归不能中断,如果组件树层级很深,递归工夫就多,线程开释不进去,就会造成卡顿,因为数据保留在递归栈中被称为stack Reconciler。react16将递归的无奈中断更新重构为异步的可中断更新,反对工作不同优先级,可中断与复原,复原后可利用之前的中间状态。每个工作更新单元为React Element对应的Fiber节点,基于Fiber节点实现叫Fiber Reconciler Fiber的构造function FiberNode( tag: WorkTag, pendingProps: mixed, key: null | string, mode: TypeOfMode,) { // 作为静态数据构造的属性 this.tag = tag; this.key = key; this.elementType = null; this.type = null; this.stateNode = null; // 用于连贯其余Fiber节点造成Fiber树 this.return = null;// 指向父级Fiber节点 this.child = null;// 指向子Fiber节点 this.sibling = null;// 指向左边第一个兄弟Fiber节点 this.index = 0; this.ref = null; // 作为动静的工作单元的属性,保留本次更新造成的状态扭转相干信息 this.pendingProps = pendingProps; this.memoizedProps = null; this.updateQueue = null; this.memoizedState = null; this.dependencies = null; this.mode = mode; //保留本次更新会造成的DOM操作 this.effectTag = NoEffect; this.nextEffect = null; this.firstEffect = null; this.lastEffect = null; // 调度优先级相干 this.lanes = NoLanes; this.childLanes = NoLanes; // 指向该fiber在另一次更新时对应的fiber this.alternate = null;}作为架构来说,每个Fiber节点有对应的React element,多个Fiber节点是靠this.return,this.child,this.sibling3个属性连接成树的如组件构造对应的Fiber树,用return代指父节点 ...

April 15, 2021 · 1 min · jiezi

关于react.js:React实现阿里云播放器视频列表循环播放

我的项目须要一个列表循环播放视频的性能,应用的是阿里云公有加密,先说一下实现思路。 申请视频列表数据首次默认第一条视频列表数据自动播放第一条数据播放完结自动更新索引值加载下一个视频。因为播放器是须要dom构造加载的,所以须要应用componentDidMount办法加载渲染播放器,咱们页面加载的第一次申请将通过它实现。 阿里云播放器自定义组件我给自定义播放组件提供了componentWillReceiveProps办法,用于跟踪配置文件变动,重载播放器播放视频。 接下来是实现的代码 import React from 'react';import Router, {withRouter} from 'next/router'import styles from './index.module.scss'import Aliplayer from "@/components/aliplay";import Head from 'next/head'export default withRouter( class PlayList extends React.Component { constructor(props) { super(props); this.handleCoursePlayBtnClick = this.handleCoursePlayBtnClick.bind(this) this.videoPlayer = React.createRef(); } state = { showDataSource: [], showPlayer: false, instance: null, playNextStatus: true, selectedPlayIndex: 0, } componentDidMount() { this.init() } async init() { const response = await api.getList() try { var data = response.data || [] if (data.length > 0) { let firstVideo = data[0] this.setState({selectedPlayIndex: 0}) this.getInfo(firstVideo.vid) } this.setState({showDataSource: data}) } catch (e) { } } handleCoursePlayBtnClick(index, vid) { this.getInfo(vid) this.setState({selectedPlayIndex: index}) } async getInfo(vid) { var playerConfig = { vid: "", playauth: "", width: '100%', height: '100%', autoplay: true, // 自动播放 useH5Prism: true, // 播放器类型:html5 preload: true, } if (!vid) { throw Error("未提供vid") } var video = {} const responseVideo = await api.getAuth(video.videoSourceId) try { playerConfig.playauth = responseVideo.playAuth } catch (e) { delete playerConfig.playauth delete playerConfig.vid } this.setState({ video: video, playerConfig: playerConfig, }) // console.log("课程加载实现", playerConfig,this.state.showPlayer) } onGetInstance = (player) => { let that = this player.on('ended', async function (e) { if (that.state.playNextStatus) { that.setState({playNextStatus: false}) that.playNextVideo() } setTimeout(() => { that.setState({playNextStatus: true}) clearTimeout() }, 800) // console.log("播放器完结播放", e) }) player.on('playing', function (e) { console.log("播放中") }) player.on('ready', function (e) { console.log("视频准备就绪,行将播放") }); player.on('error', function (e) { console.log("呈现谬误", e) }); player.on('autoplay', function (data) { //能够自动播放 data.paramData }) } playNextVideo = () => { let that = this const dataSource = that.state.dataSource let index = (dataSource.length > that.state.selectedPlayIndex + 1) ? (that.state.selectedPlayIndex + 1) : 0; let id = dataSource[index] && dataSource[index].id that.getInfo(id) that.setState({selectedPlayIndex: index}) } render() { const {showDataSource, selectedPlayIndex, playerConfig, showPlayer} = this.state return ( <div className="match video-page"> <Head> <script src={'https://g.alicdn.com/de/prismplayer/2.8.2/aliplayer-min.js'} type={'text/javascript'}/> <link href={'https://g.alicdn.com/de/prismplayer/2.8.2/skins/default/aliplayer-min.css'} rel={'stylesheet'}/> </Head> <div className={styles.main + " row match content-start"}> <div className={styles.videoListBox + " h-match cell-scroll-y"}> <div className={styles.listBtn}> <img className={styles.listBtnIcon} alt="" src={"/logo_sign.png"}/> </div> <div className="col content-start match"> <ul className={styles.videoList}> {showDataSource && showDataSource.map((video, i) => { return ( <li className={styles.videoCard + " " + (selectedPlayIndex === i && styles.videoCardActived)} key={i}> <div className="w-match p-2 col"> <div className={styles.imageBox} onClick={() => this.handleCoursePlayBtnClick(i, video.id)}> <img className={styles.videoImage} alt="" src={video.videoCover}/> </div> <div className={styles.title} onClick={() => this.handleCoursePlayBtnClick(i, video.id)}>{video.title}&nbsp;</div> </div> </li> ) })} </ul> </div> </div> <div className={styles.playerContainer + " match bg-black"}> <div className={styles.videoContainer}> <div ref={this.videoPlayer} style={{height: this.state.height}} className={"col " + styles.videoBox}> {(showPlayer && playerConfig) && <Aliplayer config={playerConfig} onGetInstance={instance => this.onGetInstance(instance)} />} </div> </div> </div> </div> </div> ); } })这里是开发过程中发现并解决的几个点:1、播放器在完结播放并进行下一个视频播放时,会屡次触发ended事件,其问题本源就是该播放器状态为完结时,我进行切换下个视频,此时ended事件再次或屡次激活,导致跳过多个视频。2、循环播放列表须要对index索引判断,进行播放视频内容更新; ...

April 14, 2021 · 2 min · jiezi

关于react.js:从零创建webpack4react项目

从零创立webpack4+react我的项目创立我的项目文件夹,并进入文件夹 mkdir webpck-react-democd webpck-react-demo初始化我的项目,生成package.json npm init -y装置webpack及其脚手架 --save-dev 开发时的依赖 --save 运行时的依赖node 5 以上版本在执行npm install命令时会主动生成package-lock.json文件package.json与package-lock.json的区别npm install --save-dev webpack webpack-cli创立并进入config文件夹 mkdir configcd config创立 webpack.common.config.js 文件 cat > webpack.base.config.js // 创立文件Crtl+D // 退出并保留const path = require('path');module.exports = { entry: { // 入口文件 app: './src/app.js', }, output: { // 编译打包后的文件名及所在门路 filename: 'js/budle.js', // 打包输入的文件名字 path: path.resolve(__dirname, '../dist') // 输入门路 }}在webpck-react-demo我的项目文件夹下创立src文件夹,并在src中创立app.js文件 创立文件能够应用命令,也能够间接手动创立~cd ../mkdir src cd srccat > app.jsCrtl + Dpackage.json文件减少运行命令 新增 start 命令"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "webpack --config ./config/webpack.base.config.js"},此时的我的项目构造 ...

April 14, 2021 · 2 min · jiezi

关于react.js:react组件的新旧生命周期

1、生命周期(旧)constructor:结构器,能够用来初始化数据和接管参数propscomponentWillMount:组件将要挂载的钩子render:数据渲染,组件挂载在页面上的钩子罕用 componentDidMount:组件挂载结束的钩子, ---------->罕用--------------> 个别做初始化的事件,例如:开启定时器,发送网络申请,订阅音讯罕用 componentWillUnmount:组件将要卸载的钩子, ---------->罕用-------------->个别做一些收尾的事件,敞开定时器,勾销订阅音讯shouldComponentUpdate:管制组件更新的阀门,必须return true/false;通过setState进行触发componentWillUpdate:组件将要更新的钩子,当shouldComponentUpdate返回false时,不触发,也能够通过this.forceUpdate()强行触发componentDidUpdate:组件更新结束的钩子componentWillReceiveProps:子组件接管父组件参数时调用(第一次除外)总结归类初始化阶段: 由ReactDOM.render()触发---首次渲染 1.constructor()2.componentWillMount()3.render()4.componentDidMount()更新阶段: 由组件外部this.setSate()或父组件从新render触发 1.shouldComponentUpdate() 2.componentWillUpdate() 3.render() 4.componentDidUpdate()卸载组件: 由ReactDOM.unmountComponentAtNode()触发 1.componentWillUnmount() 2、生命周期(新)总结归类初始化阶段: 由ReactDOM.render()触发---首次渲染 1.constructor()2.getDerivedStateFromProps 3.render()4.componentDidMount()更新阶段: 由组件外部this.setSate()或父组件从新render触发 1.getDerivedStateFromProps2.shouldComponentUpdate()3.render()4.getSnapshotBeforeUpdate//在更新之前获取快照5.componentDidUpdate()卸载组件: 由ReactDOM.unmountComponentAtNode()触发 1.componentWillUnmount() 3、重要的钩子1.render:初始化渲染或更新渲染调用2.componentDidMount:开启监听, 发送ajax申请3.componentWillUnmount:做一些收尾工作, 如: 清理定时器4、行将废除的钩子1.componentWillMount2.componentWillReceiveProps3.componentWillUpdate//当初应用会呈现正告,下一个大版本须要加上UNSAFE_前缀能力应用,//当前可能会被彻底废除,不倡议应用。

April 13, 2021 · 1 min · jiezi

关于react.js:react组件三大核心属性statepropsrefs

1、statestate是组件对象中十分重要的属性,值以对象的模式进行存储。通过state更改,从而更新页面显示的内容。组件中render办法中的this指向实例对象,调用了1+n次,其中1是初始时调用。state扭转状态不能间接批改,要通过setState()进行状态变更。初始化state state = { isHot: false,};render渲染 事件绑定须要用onClickrender() { return ( <h1 onClick={this.changeWeater}> 今天天气很{this.state.isHot ? "酷热" : "凉快"} </h1> );}setState批改值 组件自定义的办法中this为undefined,如何解决?1、强制绑定this: 通过函数对象的bind()2、箭头函数changeWeater = () => { console.log("此处批改isHot的值", this); this.setState({ isHot: !this.state.isHot, });}整体代码 <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>state的简写形式</title></head><body> <div id="test"></div> <!-- 引入react外围库 --> <script type="text/javascript" src="../js/react.development.js"></script> <!-- 反对react对dom进行操作 --> <script type="text/javascript" src="../js/react-dom.development.js"></script> <!-- 将jsx转为js --> <script type="text/javascript" src="../js/babel.min.js"></script> <script type="text/babel"> class Weater extends React.Component { // 初始化状态 state = { isHot: false, }; // 自定义办法,用赋值语句的模式+箭头函数 changeWeater = () => { console.log("此处批改isHot的值", this); this.setState({ isHot: !this.state.isHot, }); } render() { console.log(this); return ( <h1 onClick={this.changeWeater}> 今天天气很{this.state.isHot ? "酷热" : "凉快"} </h1> ); } } ReactDOM.render(<Weater />, document.getElementById("test")); </script></body></html>2、propsprops属性是只读的,不能对他进行批改。通过Person.propTypes/static propTypes对标签属性进行类型、必要性限度,其中Person为class类。通过Person.defaultProps/static defaultPropTypes设置属性默认值const p = { name: "tom" }; <Person {...p},通过{...p}进行传值// 对标签属性进行类型、必要性限度Person.propTypes={ name:PropTypes.string.isRequired,//限度name为字符串,必填 sex:PropTypes.string, age:PropTypes.number, speak:PropTypes.func//限度speak为函数}// 指定默认属性值Person.defaultProps={ sex:'男', age:14}class Person extends React.Component { constructor(props) { super(props) console.log(props) } render() { console.log(this) // props是只读的 return ( <ul> <li>姓名:{this.props.name}</li> <li>年龄:{this.props.age}</li> <li>性别:{this.props.sex}</li> </ul> ); } // 对标签属性进行类型、必要性限度 static propTypes = { name: PropTypes.string.isRequired,//限度name为字符串,必填 sex: PropTypes.string, age: PropTypes.number, } // 指定默认属性值 static defaultProps = { sex: '男', age: 14 }}const p = { name: "tom" }ReactDOM.render(<Person {...p} />, document.getElementById("test"));3、refs1、字符串模式 ...

April 9, 2021 · 2 min · jiezi

关于react.js:从零到一搭建React组件库

最近始终在捣鼓如何搭建实用的组件库,至于为什么会产生这个想法,次要是因为组件库对于前端生态来说究极重要,每一个着眼于久远倒退的互联网公司基本上都会量身定制组件库,它的益处不必多说,读者们在应用中或多或少都会领会到一些长处,如果以前做过MVC,那么对于这一点的领会必定更加粗浅。一款组件库如此之重要,作为一名前端工程师应该去深刻的理解,为当前工作开发、职业倒退赋能。 大抵来说,开发一款组件库通常会有以下几点益处: 对立产品设计体验进步团队合作效率升高开发成本性能需要在做任何一件事件之前都应该捋分明咱们的初衷,也就是咱们的需要是什么,凡事预则立,不预则废。 这里撇开业务上的需要,因为这篇文章没有基于业务场景去思考。只梳理一些性能上需要,也就是如何搭建一个高性能、高实用、高标准的React组件库。 需要清单: 满足ES Module、CommonJS、AMD、CMD模块引入形式反对按需加载技术选型~~~~环境搭建搭建组件库首先咱们来搭建工程环境,这里咱们不采纳create-react-app脚手架来搭建,因为脚手架封装好了很多货色,而有些货色对于组件库并不实用,用来搭建组件库过于臃肿。因而,我筹备从零到一搭建React组件库。 首先,先创立一个工程文件夹,执行npm init命令生成package.json;执行tsc --init生成tsconfig.json 而后,按如下构造组织工程的目录构造: pony-react-ui - src - assets // 寄存动态文件,比方图片、文字等 - components // 组件 - styles // 组件款式 - index.ts // 主文件入口 - style.ts // 款式文件入口 - package.json // 依赖治理 - tsconfig.json // ts配置 - webpack.config.js // webpack配置如何组织组件在components文件夹下以如下形式组织组件,比方创立一个Button组件 - components - Button - Button.tsx // 按钮组件 - index.tsx // 组件入口 - Dialog - Dialog.tsx - index.tsxButton.tsx import React from 'react';import classNames from 'classnames';export interface IButtonProps { onClick?: React.MouseEventHandler; // 类型 primary?: boolean; secondary?: boolean; outline?: boolean; dashed?: boolean; link?: boolean; text?: boolean; // 尺寸 xLarge?: boolean; large?: boolean; small?: boolean; xSmall?: boolean; xxSmall?: boolean; // 色彩 success?: boolean; warn?: boolean; danger?: boolean; // 禁用状态 disabled?: boolean; className?: string; style?: React.CSSProperties; children?: React.ReactNode;}export const Button = (props: IButtonProps) => { const { className: tempClassName, style, onClick, children, primary, secondary, outline, dashed, link, text, xLarge, large, small, xSmall, xxSmall, success, danger, warn, disabled, } = props; const className = classNames( { 'pony-button': true, 'pony-button-primary': primary, 'pony-button-secondary': secondary && !text, 'pony-button-outline': outline, 'pony-button-dashed': dashed, 'pony-button-link': link, 'pony-button-text': text && !secondary, 'pony-button-text-secondary': secondary && text, 'pony-button-round': round, 'pony-button-rectangle': noRadius, 'pony-button-fat': fat, 'pony-button-xl': xLarge, 'pony-button-lg': large, 'pony-button-sm': small, 'pony-button-xs': xSmall, 'pony-button-xxs': xxSmall, 'pony-button-long': long, 'pony-button-short': short, 'pony-button-success': success, 'pony-button-warn': warn, 'pony-button-danger': danger, 'pony-button-disabled': disabled, }, tempClassName ); return ( <button type="button" className={className} style={style} onClick={onClick} disabled={disabled}> <span className="pony-button__content">{children}</span> </button> );}在index.tsx抛出组件以及该组件的类型申明 ...

April 8, 2021 · 2 min · jiezi

关于react.js:前端仿Chrome实现标签栏react2

上个版本的标签栏实现了标签切换以及右键菜单性能。这几天利用闲余工夫加上了拖动性能: GitHub 次要参考了React 实现繁难的图片拖动排序 实现思路本来想应用onDragStart/onDragOver/onDragEnd事件来实现,但因为标签的款式实现形式影响,拖动进去的款式乱掉了,因而pass掉,还是应用onMouseDown/onMouseMove/onMouseEnd实现: 每一个标签监听onMouseDown事件 记录以后点击的标签(movingTagPath)一些地位(originMousePos/originTagPos)设置以后标签为选中状态document监听mousemove及mouseup事件 mousemove处理函数中计算挪动的间隔,(解决边界值后)设置movingTagPosmouseup处理函数中重置movingTagPos/movingTagPath并移除document监听的事件标签父元素监听onMouseMove事件 解决拖动过程中标签地位更新逻辑//onMouseDown handlerconst onTagMouseDown = useCallback((e, path) => { e.preventDefault(); movingTagPath.current = path; const x = (parseInt(e.currentTarget.style.left, 10) || 0); originMousePos = { x: e.pageX, y: 0 }; originTagPos = ({ x, y: 0 }); const activeTag = contentDivRef.current?.querySelector(`.${style.active}`); activeTag?.setAttribute('class', style.tagC); e.currentTarget?.classList.add(style.active); e.currentTarget?.classList.add(style.moving); setMovingTagPos({ x: 0, y: 0 }); document.addEventListener('mousemove', onTagMouseMove); document.addEventListener('mouseup', onTagMouseUp);}, [onTagMouseMove, onTagMouseUp]);// mousemove及mouseupconst onTagMouseMove = useCallback((e) => { e.preventDefault(); const contentWidth = (contentDivRef.current?.getBoundingClientRect().width || 0); const contentLeft = (contentDivRef.current?.getBoundingClientRect().left || 0); // 边界值解决 const threshold = (contentLeft + (TAG_WIDTH / 2)); if (e.pageX < threshold) { setMovingTagPos({ x: 0, y: 0 }); return; } let x = e.pageX - originMousePos.x + originTagPos.x; x = x > contentWidth - threshold ? contentWidth - threshold : x; setMovingTagPos({ x, y: 0 });}, []);const onTagMouseUp = useCallback(() => { document.removeEventListener('mousemove', onTagMouseMove); document.removeEventListener('mouseup', onTagMouseUp); setMovingTagPos({ x: 0, y: 0 }); movingTagPath.current = '';}, [onTagMouseMove]);// onMouseMove handlerconst onTagOver = useCallback((e) => { e.preventDefault(); updateTags(e.clientX);}, [updateTags]);const updateTags = useCallback((clientX: number) => { const dropRect = contentDivRef.current?.getBoundingClientRect(); if (dropRect && movingTagPath.current) { const offsetX = clientX - dropRect.left; const dragItem = tags.find((item) => item.path === movingTagPath.current) || { path: '', title: '' }; const col = Math.floor(offsetX / TAG_WIDTH); let currentIndex = col; const fromIndex = tags.indexOf(dragItem); if (fromIndex < currentIndex) { currentIndex += 1; } const currentItem = tags[currentIndex]; const ordered = insertBefore(tags, dragItem, currentItem); if (isEqualBy(ordered, tags, 'path')) return; // 改正更换程序后标签地位偏移 if (fromIndex < currentIndex) { originMousePos.x += TAG_WIDTH; } else { originMousePos.x -= TAG_WIDTH; } setTags(ordered); }}, [tags]);

April 2, 2021 · 2 min · jiezi

关于react.js:前端仿Chrome实现标签栏react1

想给本人的后盾增加一个标签切换组件,没找到适合的,正好看到Chrome的标签栏,切换起来十分丝滑,于是便借鉴剽窃一下 成果预览 CodeSandbox Github :拖动已实现 实现思路简略说一下标签栏和右键菜单实现,具体参照代码 标签栏 <div className="container"> <div className="top" /> <div className="content"> <div onContextMenu={(e) => onTagContextMenu(e, tag.path)} className={`tag-c ${currentTag === tag.path ? "active" : ""}`} > <span className="tag-text">{tag.title}</span> <span className="tag-close">X</span> </div> </div> <div className="bottom" /></div.tag-c { padding: 10px; border-top-left-radius: 10px; border-top-right-radius: 10px; padding: 8px 10px 0; position: relative; cursor: pointer; font-size: 14px; width: 120px; box-sizing: border-box; background-color: #ccc; display: flex; justify-content: space-between; align-items: center;}.tag-c.active { background-color: #ddd;}.tag-c.active::before { position: absolute; content: ""; height: 5px; width: 9999px; background-color: #ccc; left: -9999px; border-bottom-right-radius: 10px; bottom: -5px;}.tag-c.active::after { position: absolute; content: ""; height: 5px; width: 9999px; background-color: #ccc; left: 120px; border-bottom-left-radius: 10px; bottom: -5px;}整个div.container设置一个背景色,选中的div.tag-c设置高亮背景色div.bottom设置高亮色增加上部圆角,应用div.tag-c的border-radius实现增加下部圆角,应用div.tag-c::after和div.tag-c::before实现顶部增加div.top是为了占位,不便div.content居中 ...

April 2, 2021 · 1 min · jiezi

关于react.js:关于react-回掉函数中拿不到最新state的问题

有时候,咱们在以后组件里注册了第三方插件的事件回调,回掉函数的参数是第三方抛出来的数据,咱们在这个回掉里,可能还须要拜访以后组件里state,然而你很有可能就会遇到始终拿到的是第一次的state,上面开始上代码。 const [info, setInfo] = useState();const [isEnd, setIsEnd] = useState(false);useEffect(() => { const callBackId1 = Plus.reigsterCallBack1((info) => { setInfo(info); }); const callBackId2 = Plus.reigsterCallBack2(info2 => { if (info2.id === info.id) { //这里的info将会永远都是null setIsEnd(true); } }); return () => { Plus.unregisterCallBack(callBackId1); Plus.unregisterCallBack(callBackId2); };}, []);计划1: useRef const [info, setInfo] = useState();const [isEnd, setIsEnd] = useState(false);const instRef = useRef();//新增useEffect(() => { const callBackId1 = Plus.reigsterCallBack1((info) => { setInfo(info); instRef.current = info;//新增 }); const callBackId2 = Plus.reigsterCallBack2(info2 => { if (info2.id === instRef.current.id) {//批改 setIsEnd(true); } }); return () => { Plus.unregisterCallBack(callBackId1); Plus.unregisterCallBack(callBackId2); };}, []);计划2:useCallback ...

April 1, 2021 · 1 min · jiezi

关于状态管理:状态管理VueX与Redux

一、概览Redux与VueX是目前利用最广的前端框架的状态治理解决方案,其中Vuex是官网推出的计划,而Redux是React社区提供的。2014年 Facebook 提出了 Flux 架构的概念,引发了很多的实现。2015年,Redux 呈现,将 Flux 与函数式编程联合一起,通过屡次迭代更新,目前曾经成为React生态中的最受欢迎的解决方案。VueX是追随Vue一起公布的状态管理工具,Vue自称是一个渐进式的框架,就意味着其实VueX跟Redux一样能够依据本人的需要来选装。它也借鉴了Flux的思维。二、外围概念比照1、Redux(1)Web 利用是一个状态机,视图与状态是一一对应的。(2)所有的状态,保留在一个对象外面。(这两个观点是阮一峰老师的博客里讲的,很精炼,所以拿来间接用了。)(3)action:同步action ,或借助 中间件 实现异步操作,action不会扭转 store,只是形容了怎么扭转store。(4)reducer(纯函数,依据 action 和旧的 store 计算出新的 store。(5)store:繁多数据源。(6) Redux 提供了 store.getState() 这个 API 获取 store 树,还有 store.subscribe(listener)订阅 store 的变动,当 store 扭转时会调用监听器;(7)Redux 能够通过 combineReducers()联合各个组件的 reducer,各个组件能够独自治理本人的状态,最初合并为一个 reducer 用于生成一个 store;(8)将状态数据绑定到视图:Redux 将状态映射到视图能够通过 React-redux 映射到 React 组件, 当然也能够间接应用 Redux 本人提供的 store.subscribe() 订阅 store 的扭转,从而更新视图,因而 Redux 不仅仅能够用于 React,也能够用于其余框架如 Vue;2、VueX(1)mutation(用于同步操作)(2)action(可用于异步操作,提交 mutation)(3)mutation外面间接批改 state(4)state(繁多数据源)(5)Vuex 有一个 getter 的概念用于依据 state 派生出一些数据,像 Vue 的计算属性一样,当 state 扭转时会从新计算出一个后果进去,提供给须要的组件。(6)Vuex 用 Module 这个概念划分 store,与 Redux 一样,能够多层嵌套子状态。(7)将状态数据绑定到视图: Vuex 只能用于 Vue,它提供了 mapState、mapAction、mapMutations 等API 将 store 映射到 Vuex 各个组件,这个参考了 React-redux 的 mapStateToProps。三、应用准则Redux 应用准则:1.繁多数据源(一个Redux利用只有一个store),也是单向的数据流;2.state只读(惟一扭转 state 的办法就是触发 action,action 是一个用于形容已产生事件的一般对象。);3.应用纯函数(reducer)来批改state。 ...

April 1, 2021 · 1 min · jiezi

关于react.js:react高阶组件Hoc

1. 在class组件流行之后,咱们能够通过继承的形式进一步的强化咱们的组件。这种模式的益处在于,能够封装根底性能组件,而后依据须要去extends咱们的根底组件,按需强化组件,然而值得注意的是,必须要对根底组件有足够的把握,否则会造成一些列意想不到的状况产生。class Base extends React.Component{}2.

March 30, 2021 · 1 min · jiezi

关于react.js:React-warningcannot-update-a-component

问题形容: 解决方案:How to fix the "cannot update a component while rendering a different component" error in React

March 30, 2021 · 1 min · jiezi

关于react.js:react父组件调用子组件的方法

办法:父组件应用 useRef 创立一个 ref 传入 子组件 ...const childrenRef = useRef(null);...return <children ref={childrenRef} />复制代码子组件须要应用 useImperativeHandle 裸露 ref 自定义的实例值给父组件。这个须要用 forwardRef 包裹着。 function children(props, ref) { useImperativeHandle(ref, () => ({ hello: () => console.log('hello world!') })) return <h1>children</h1>}export default forwardRef(children);复制代码那么在父组件怎么调用呢? ...const childrenRef = useRef(null);const something = () => childrenRef.current.hello();...复制代码倡议:还是能够查看一下实现办法的关键点: useRef, useImperativeHandle, forwardRef。其实是利用了 ref 不变的性质,将子组件的办法保留着,父组件能够调用。能够说,ref 作为父组件和子组件的一座由父组件达到子组件的桥梁(单向的,父->子)

March 29, 2021 · 1 min · jiezi

关于react.js:在React中使用Electron

本文用于记录在react-create-app生成的react我的项目中配置electron的步骤。残缺我的项目见github成果: 应用react-create-app生成react我的项目。装置electron:npm install electron 如果装置过程中在install.js出错,可参考:解决装置electron卡在node install.js 不动问题。在package.json中的最外层退出: "homepage": "./","main": "main.js",如图: 在package.json中的scripts内退出:"electron": "electron ." 如图:应用npm run build命令打包,在根目录的build文件夹下生成react我的项目的index.js文件,用于electron的渲染过程拜访。在我的项目的根目录下(即与src同级处)新建一个文件main.js。文件的内容如下:// 引入electron并创立一个Browserwindowconst {app, BrowserWindow} = require('electron');const path = require('path');const url = require('url');// 放弃window对象的全局援用,防止JavaScript对象被垃圾回收时,窗口被主动敞开.let mainWindowfunction createWindow () {//创立浏览器窗口,宽高自定义mainWindow = new BrowserWindow({width: 800, height: 600}) /* * 加载利用----- electron-quick-start中默认的加载入口 */ mainWindow.loadURL(url.format({ //应用npm run build生成的index.html的路径名 pathname: path.join(__dirname, './build/index.html'), protocol: 'file:', slashes: true })) // 关上开发者工具,默认不关上 // mainWindow.webContents.openDevTools() // 敞开window时触发下列事件. mainWindow.on('closed', function () { mainWindow = null })}// 当 Electron 实现初始化并筹备创立浏览器窗口时调用此办法app.on('ready', createWindow)// 所有窗口敞开时退出利用.app.on('window-all-closed', function () { // macOS中除非用户按下 `Cmd + Q` 显式退出,否则利用与菜单栏始终处于活动状态. if (process.platform !== 'darwin') { app.quit() }}) app.on('activate', function () { // macOS中点击Dock图标时没有已关上的其余利用窗口时,则通常在利用中重建一个窗口 if (mainWindow === null) { createWindow() } })

March 28, 2021 · 1 min · jiezi

关于react.js:React前段学习一

什么是React?React 是一个用于构建用户界面的 JavaScript 库React官网文档:https://react.docschina.org/ React 从诞生之初就是可被逐渐采纳的 HTML 中应用 React<!DOCTYPE html><html><head> <meta charset="UTF-8"/> <title>Add React in HTML</title></head><body><!-- 操作的容器 --><div id="root"></div></body><!-- 引入 react 操作dom得js --><script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script><script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script><!-- 如果你想应用 JSX 语法 这个js必须引入 --><!-- React 举荐应用 JSX 语法配合应用 --><script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script><!-- React 代码 --><script></script></html>Hello World页面上展现一个 "Hello, world!" ReactDOM.render( <h1>Hello, world!</h1>, document.getElementById('root'));JSXconst element = <h1>>Hello, world!</h1>;ReactDOM.render( element, document.getElementById('root'));在 JSX 中嵌入表达式const name = 'Shao Jie';const element = <h1>Hello, {name}</h1>;ReactDOM.render( element, document.getElementById('root'));在 JSX 语法中,能够在大括号内搁置任何无效的 JavaScript 表达式。例如:2 + 2,user.firstName function formatName(user) { return user.firstName + ' ' + user.lastName;}const user = { firstName: 'Shao', lastName: 'Jie'};const element = ( <h1> Hello, {formatName(user)}! </h1>);ReactDOM.render( element, document.getElementById('root'));这货色像不像 Java 外面的面向对象在编译之后,JSX 表达式会被转为一般 JavaScript 函数调用,并且对其取值后失去 JavaScript 对象。也就是说,你能够在 if 语句和 for 循环的代码块中应用 JSX,将 JSX 赋值给变量,把 JSX 当作参数传入,以及从函数中返回 JSX: ...

March 24, 2021 · 2 min · jiezi

关于react.js:快速上手React

web前端三大支流框架 1、Angular 大家眼里比拟牛的框架,甚至有人说三大框架中只有它能称的上一个残缺的框架,因为它蕴含的货色比较完善,蕴含模板,数据双向绑定,路由,模块化,服务,过滤器,依赖注入等所有性能。对于刚开始学习应用框架的小伙伴们,能够举荐这个框架,学会之后几乎能颠覆之前你对前端开发的认知。应用 TypeScript可能进步代码可维护性,有利于前期重构。双向数据流很不便,然而等业务简单之后,你可能就搞不清楚数据流了。还有令人不开心的脏值查看,以及directive的封装并没有解决视图与数据关系齐全拆散,有时候还要用$digist强制触发检测。 2、React(也是接下来要讲的) 这个框架自身比拟容易了解,它的构造很清晰,就是由十几个API组成,而后异步渲染,咱们只须要解决好接口和保护就好了,然而很多人反映上手还是有肯定的的难度的。React是单向数据流,代码写起来会较双向数据流的多一些,然而同样的排查问题时思路清晰很多。 3、Vue 号称是最简略,最容易上手的框架,同时也是行内的大趋势,还能够用来开发最火的小程序。毕竟用这神器,代码码的飞快,我的项目也能疾速上线。同时他也是双向数据流。有些人认为Vue是Angular和React的联合,既有Angular的模板语法也有React的组件化体系。 React 简介 React 起源于 Facebook 外部我的项目,用来架设 Instagram 网站,并于 2013 年 5 月开源。React 领有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和应用它。 1、React 次要的原理 Virtual DOM 虚构 DOM; 传统的 web 利用,操作 DOM 个别是间接更新操作的,DOM 更新通常是比拟低廉的。而 React 为了尽可能减少对 DOM 的操作,提供了一种不同的而又弱小的形式来更新 DOM,代替间接的 DOM 操作。就是 Virtual DOM,一个轻量级的虚构的 DOM,就是 React 形象进去的一个对象,形容 DOM 应该什么样子的,应该如何出现。通过这个 Virtual DOM 去更新实在的 DOM,由这个 Virtual DOM 治理实在 DOM 的更新。React 有个 diff 算法,更新 Virtual DOM 并不保障马上影响实在的 DOM,React 会等到事件循环完结,而后利用这个 diff 算法,通过以后新的 dom 表述与之前的作比拟,计算出最小的步骤更新实在的 DOM。2、应用 React 利用脚手架 create-react-app ...

March 23, 2021 · 2 min · jiezi

关于react.js:react动态设置ClassName

<div className={`container tab ${index===this.state.currentIndex?"active":null}`}>此标签是否选中</div>

March 23, 2021 · 1 min · jiezi

关于react.js:react中关于hook介绍及其使用

前言 最近因为公司的我的项目开发,就学习了在react对于hook的应用,对其有个根本的意识以及如何在我的项目中去利用hook。在这篇博客中次要从以下的几个点进行介绍: hook简介hook中罕用api的应用hook在应用过程中须要去留神的中央hook中怎么去实现class组件中的申明周期函数hook 首先介绍对于hook的含意,以及其所要去面对的一些场景 含意:Hook 是 React 16.8 的新增个性。它能够让你在不编写 class 的状况下应用 state 以及其余的 React 个性。简略来说就是能够应用函数组件去应用react中的一些个性所要解决的问题:解决组件之间复用状态逻辑很难得问题,hook能解决的就是在你无需批改之前组件构造的状况下复用状态逻辑,在不应用hook的状况下,须要应用到一些高级的用法如高级组件、provider、customer等,这种形式对于老手来说不太敌对,可能在了解上就比拟的艰难对于简单组件能够去拆分其逻辑,例如在你应用生命周期函数时,不同的生命周期须要在不同的时刻进行,因而在此时对于简单的组件来说,有的生命周期函数中就存在大量的逻辑,在可读性下面就大打折扣。当应用hook时,就能够进行组件逻辑的划分,将雷同的逻辑给整合在一起,这样就大大增加可读性也在一方面利于保护不须要对于class组件的了解,当你在最后去学习时,你不得不去了解this这个关键字,在以后组件所示意的含意,然而在hook中就不须要。可能解决你在不应用class组件的状况上来体现react的个性须要留神的一点就是hook和class组件是不可能同时应用的,在理论的应用过程中肯定要留神,否则就会呈现报错那么接下来所要介绍的局部就是如何去应用hook state hook 对于应用过class组件的同学,置信对于state必定有很深的印象,对于一些须要用到的全局变量,在class组件中咱们经常采纳的形式是this.state = {},然而在hook中咱们采纳的形式就是应用useState这个hook,而后就能够对这种全局变量进行援用,在援用时只须要用其变量名即可,这里就拿官网的例子来举例: 在下面的这个例子中,咱们设置变量形式采纳的就是const [count, setCount] = useState(0)这种形式,其中的0就是给count赋初值为0,如果想要给count赋值为一个空对象,那么只须要const [count, setCount] = useState({}),这样的形式就行了,那么这样你在用count时,此时获取到的值就为一个空对象。作用:返回一个state,以及更新state的函数函数式更新:新的state须要通过应用先前的state计算得出,将函数传递给setState,该函数将接管先前的state,并返回一个更新后的值惰性初始state,initialState参数只会在组件的初始渲染中起作用,如果初始化state须要通过一个简单计算来获取,则能够传入一个函数,在函数中计算并返回初始的state,此函数只在初始渲染时被掉用,如下所示: 在hook中如何给全局变量设置值 在class组件中咱们给放在state中的变量赋值时,通常采纳的形式就是this.setState()这种形式,那么在hook中所要采纳的就是set+变量名这种形式,如 在这里通过下面咱们曾经晓得的就是count可能获取到值,那么其所对应的setCount(值),这种赋值的形式就是给count变量赋值的,而后通过count就可能获取到值。 为什么要采纳这种形式呢?起因:是因为react中的单向数据源,这样的话,可能保障你的数据源流向会更加的分明,这也是react所区别于vue中双向数据源绑定的一点hook中设置多个全局变量的形式 在hook中,如果咱们须要去设置多个相似于下面所说的count,那么就须要屡次应用useState这个hook,当然你也能够设置一个变量在hook的最内部,即在hook这个函数组件的内部。须要留神的是别在整个hook这个函数的全局设置,因而在hook的运行机制中,在每次加载时,都会从新去加载外面的变量,因而你是不可能去获取到在整个函数外部中应用该变量所扭转的值的,可能获取到的就只是这个变量的初始值* useEffect hook 对于useEffect hook,其用处相似于class组件中的生命周期函数,用来解决在一些特定时刻须要去做的事件,这种事件常被叫做副作用。在应用useEffect这个hook时,须要留神的一点就是其不可能被蕴含在循环,判断语句中,否则我的项目会呈现报错,这也是hook的一种设置机制 副作用的划分:不须要革除的: 在React更新DOM之后运行一些额定的代码:如:发送网络申请,手动变更DOM,记录日志等须要革除的:当应用内部数据源时,须要去革除数据,如:定时器,须要咱们在完结的时候去革除渲染机会:在应用useEffect这个hook时,须要留神的就是其渲染的机会,默认状况下会在第一次渲染和每一次更新时去执行。对于如何去管制这个渲染机会,在上面的一个局部会有具体的介绍作用:通知组件在渲染之后执行某些操作useEffect放在组件外部调用的起因:能够在effect中间接拜访state中的变量effect返回函数:effect可选的革除机制,每个effect都能够返回一个革除函数接管内容:一个蕴含命令式、并且可能有副作用代码的函数革除effect:实现形式,effect函数须要返回一个革除函数effect执行机会:在浏览器实现布局和绘制之后,传给useEffect的函数会提早调用,因而不应该在函数中执行足赛浏览器更新屏幕的操作。默认条件执行:会在每轮组件渲染实现后执行,因此一旦effect的依赖发生变化,他就会被从新创立。要扭转其执行机会,须要给useEffect传递第二个参数,只有当第二个参数值产生扭转才会从新创立订阅。如果要应用这个优化的形式,须要确保数组蕴含了所有内部作用域中会发发生变化,且在effect中应用的变量。如果只想运行一次effect,能够传递一个空数组作为第二个参数。对于useEffect的初步意识只须要理解下面的即可。接下来就来介绍一个官网的实例,来阐明useEffect 在下面的这段代码中,就应用到了useEffect这个hook,在每次count值扭转时,就会在页面中去打印“You clicked ${count} times”这段文字,当然count必定对应的就是其所对应的值。 useEffect去取代calss中的生命周期函数的形式 react中有状态组件中,其生命周期函数的各个阶段 在Mounting阶段constructor()static getDerivedStateFromProps()render()componentDidMount()2. Updating static getDerivedStateFormPropsshouldComponentUpdate()render()getSnapshotBeforeUpdate()componentDidUpdate()3. UnMouting componentWillUnmount()应用hook去代替生命周期函数的形式 constructor: 能够通过useState来初始化statecomponentDidMount(),在hook中须要应用上面的这种形式去取代,在useEffect中传递第二个参数,该参数为一个空数组,只会去执行一次,如上面所示 componentDidUpdate(),有两种形式去解决在每次渲染的时候都去调用hooks,解决的形式如上面所示useEffect(() => { }) 用一个非凡变量的去触发hook,如上面所示,count指的就是这个非凡的变量,该hook触发,只会是count的值扭转时useEffect(() => { },[count]) ...

March 22, 2021 · 1 min · jiezi

关于react.js:useEffect进阶指南上

每次渲染都有独立的状态(State)`function Demo() {  const initCount = 0  const [count, setCount] = useState(initCount)    return (    <div>      <h2>{count}</h2>      <button onClick={() => setCount(count + 1)}>count++</button>    </div>  ) }` 每当用户点击一次按钮 都会从新触发render函数,每次render拿到的都是独立的状态 因为咱们生命count的值时应用const,所以每次渲染拿到的count值是一个独立的常量。 每次渲染都有不同且独立的函数(Effect函数)`function Demo() {  const initCount = 0  const [count, setCount] = useState(initCount)    // 假如在1s内屡次点击按钮 这里打印的count值是什么?  useEffect(() => {    setTimeout(() => {      console.log(count) // 这里打印的会是以后这一次的count值,并不是最新的count值    }, 1000)  })    return (    <div>      <h2>{count}</h2>      <button onClick={() => setCount(count + 1)}>count++</button>    </div>  ) }` 每次count值扭转,都会触发render,组件从新渲染,所以每次都会生成对应的useEffect函数 而且咱们发现每次打印count的值拿到的都是以后轮次的count值(并不是最新的count) useEffect到底是怎么拿到最新的状态值的?咱们晓得每次渲染都会触发render,每次更新就会生成一个新的Effect函数,并且每一个Effect函数外面都有独立的State,且只能拜访本人本次更新的State。 所以用下面的例子,得出的论断就是:count值其实不是在同一个Effect函数外面产生扭转,而是每一次的组件更新,都会生成一个保护着本次更新的Effect函数,在这个最新的Effect函数里就能够拜访到最新的count值。 useEffect返回的函数是如何进行清理工作的?`function Demo() {  const initCount = 0  const [count, setCount] = useState(initCount)     useEffect(() => {    let timer = setTimeout(() => {      console.log(count)    }, 1000)        // 清理工作    return () => {      clearTimeout(timer)    }  })    return (    <div>      <h2>{count}</h2>      <button onClick={() => setCount(count + 1)}>count++</button>    </div>  ) }` 假如用户点击了两次次按钮 当第一次点击的时候 count + 1 = 1,而后执行clearTimout革除本次的定时器? 接着持续count + 1 = 2 而后执行clearTimeout革除本次的定时器? 正确的程序应该是:当第一次点击 count + 1 = 1,而后clearTimeout会被提早执行,等到第二次点击的时候 count + 1 = 2 再执行上一次的clearTimeout 而后以此类推...问题来了 不是说effect函数只能拜访本次的State吗?那它怎么拿到上一次的clearTimeout并执行的? 其实很简略,就是React会帮你记住每次effect函数的State(包含革除函数),它的确是只能读取本次更新的State,只不过是提早执行了(把革除函数的执行机会放在DOM渲染实现后,在下一次render触发之前) 剩下的内容下期见吧,我累了,当初要去吃麦当劳补充一下能量... 下期预报:useEffect的第二个参数具体解析及应用,在开发中正当应用依赖(防止死循环、性能优化...)

March 21, 2021 · 1 min · jiezi

关于react.js:react-学习2

1. react 事件react 事件是不须要思考兼容性的,间接应用oneventType 绑定即可。在React中,event对象并不是浏览器提供的,你能够将它了解为React的事件对象,由React将原生浏览器的event对象进行了封装,对外提供一公共的API接口,无需思考各个浏览器的兼容性与原生浏览器处理事件的冒泡(event.stopPropatation),阻止默认行为(event.preventDefault)应用一样当在JSX上进行事件监听绑定的时候,对于JSX回调函数中的this,因为Es6中的class的办法默认不会绑定this,如果你不进行this的坏境绑定,遗记绑定事件处理函数,并把它传给事件办法(下面是onClick),那么this的值是undefined。肯定要留神this的指向问题。如果没有再结构器外面bind,就始终要在利用的时候用剪头函数。倡议是在结构器外面就绑定this。这样性能要高一些,工具类的loadsh .关注一下2. react 组件的生命周期

March 17, 2021 · 1 min · jiezi

关于react.js:一句话解释-useCallback-与-useMemo-的区别-作用

本文经作者受权转载,原文作者:HD Superman,原文链接:一句话解释 useCallback 与 useMemo 的区别 & 作用 背景最近在重构其余我的项目的代码,发现很多新手写的代码没有做好 hook 内存优化,在解释为什么须要以及 useCallback 和 useMemo 的区别,顺便写下来。 解释一句话:useCallback 缓存钩子函数,useMemo 缓存返回值(计算结果)。 type DependencyList = ReadonlyArray<any>;function useCallback<T extends (...args: any[]) => any>(callback: T, deps: DependencyList): T;function useMemo<T>(factory: () => T, deps: DependencyList | undefined): T;一些文章简明扼要解释,其实间接看 typescript 申明就晓得作用了,泛型 T 在 useCallback 中是一个钩子函数,在 useMemo 中是一个返回值。 作用一个简略计数器 demo 解释全副作用:点击按钮 count 加 1,同时显示这个数是奇数还是偶数 不必 hook 的代码import React, { FC, useCallback, useMemo, useState } from 'react';const Index: FC = (props) => { const [count, setCount] = useState(0); const isEvenNumber = count % 2 === 0; const onClick = () => setCount(count + 1); return ( <div> <div>{count} is {isEvenNumber ? 'even':'odd'} number</div> <button onClick={onClick}></button> </div> );};应用 hook 后的代码import React, { FC, useCallback, useMemo, useState } from 'react';const Index: FC = (props) => { const [count, setCount] = useState(0); const isEvenNumber = useMemo(() => { return count % 2 === 0; }, [count]); const onClick = useCallback(() => { setCount(count + 1); }, [count]); return ( <div> <div>{count} is {isEvenNumber ? 'even':'odd'} number</div> <button onClick={onClick}></button> </div> );};看起来没有什么区别,甚至应用 hook 后代码还变简单了。这个 demo 比较简单,所有应用 hook 后的优化成果不显著,大部分代码即便应用第一种写法都没有太大区别,用户无感知,但零碎逐渐降级后为了占用更小的内存、更晦涩的应用体验 hook 是必要的。 ...

March 12, 2021 · 1 min · jiezi

关于react.js:回顾学习react-1

总结起源: 掘金作者 itclanCoder 1. reactJS 是什么用于构建用户界面的javascript库,MVC架构中的V层申明式开发面向数据编程,只有把数据构建好了就能够了的,react会主动的帮你去构建网站,把数据能够了解为图纸,图纸做好了之后,react会主动的联合这张图纸帮忙你去构建这个大厦,去构建整个页面的DOM,数据是什么,页面就显示什么,这种申明式的开发帮忙咱们节约掉大量的DOM操作代码,这是react编程带来的一个劣势) 2. react 能够做什么写web利用(网站,pc端,挪动端等,例如:知乎,简书等)桌面客户端应用软件(相似vscode或者一些报表软件携带窗口的利用)webApp--react native,混合开发利用。目前曾经开发了RN 我的项目,0.59版本反对了HOOKs。如果纯熟了react,开发RN 不是问题服务器端利用(java,php等后端语言无能的事件,react也无能)3. react 中的组件我集体的了解,react组件Component不是UI组件,它是将某个特定的性能独立,能够重复使用的代码。 把一个大的利用分解成若干个小的组件,每个组件只须要关注小范畴的特定性能就能够了。react 利用就是由组件构建成的。非常适合用户交互组件4. react 特点虚构DOM通过DOM-DIFF办法算法,智慧更新由差别的局部,不必渲染整个页面,提高效率组件化把页面分成若干个组件,组件中蕴含逻辑构造和款式 组件只蕴含本身逻辑,更新组件的时候能够预测,利于保护整个页面拆分多个组件,能够做到重用单项数据流单向数据流(父组件容许向子组件传值,然而子组件你只能去应用父组件),子组件并不能间接的去改写这个值,只能单向的传递,然而你不能反过来的给我批改,想要达成这一目标,子组件调用父组件的办法,通过在父组件中扭转本人来操作,保护代码起来比拟不便)能够与其余框架并存(Jq,Angular等) 数据是从顶层组件传递到子组件中 数据可控

March 12, 2021 · 1 min · jiezi

关于react.js:初探React

1、创立react我的项目 npx create-react-app my-app(npx是 npm 5.2+ 附带的 package 运行工具)index.js为入口文件2、启动我的项目 npm start3、jsx语法 能够利用{}写js表达式,如:{1 + 2}不能写js语法if等,4、函数this 函数要通过上面bind(this)绑定TodoList组件this.handleBtnClick = this.handleBtnClick.bind(this)5、父子组件传值 父组件通过属性传值;如:content={item} index={index}react根部只能有一个元素包裹,Fragment为react的片段,在页面中不显示;能够用于根部有两个或者多个元素import React from "react";import TodoItem from "./TodoItem";class TodoList extends React.Component { constructor(props) { super(props); this.state = { list: [], inputValue: "", }; this.handleInputChange = this.handleInputChange.bind(this); this.handleBtnClick = this.handleBtnClick.bind(this); this.handleDlete = this.handleDlete.bind(this); } handleBtnClick() { this.setState({ list: [...this.state.list, this.state.inputValue], inputValue: "", }); } handleInputChange(e) { this.setState({ inputValue: e.target.value, }); } handleDlete(index) { const list = [...this.state.list]; list.splice(index, 1); this.setState({ list, }); } getTodoItems() { return this.state.list.map((item, index) => { return ( <TodoItem content={item} key={index} index={index} delete={this.handleDlete} ></TodoItem> ); }); } render() { return ( <React.Fragment> <div> <input value={this.state.inputValue} onChange={this.handleInputChange} ></input> <button className="red-btn" style={{borderRadius:'2px',padding:'5px 10px'}} onClick={this.handleBtnClick}>add</button> </div> <ul>{this.getTodoItems()}</ul> </React.Fragment> ); }}export default TodoList;子组件通过props接管;如const { index } = this.props;import React from "react";class TodoItem extends React.Component { constructor(props) { super(props); this.handleDelete = this.handleDelete.bind(this); } handleDelete() { this.props.delete(this.props.index); // const { delete , index } = this.props; // delete index; } render() { const { content } = this.props; return <div onClick={this.handleDelete}>{content}</div>; }}export default TodoItem;

March 12, 2021 · 1 min · jiezi

关于react.js:React相关

为什么用ReactReact益处: 单向数据流:函数式编程:React益处: 晋升开发效率,升高保护老本:单向数据流,view = fn(data)。依据输出数据的变动扭转界面,数据指向明确,好定位和发现问题,更好的保护。双向绑定数据流凌乱成熟欠缺的社区反对。如Redux:可追踪,可保护。跨平台页面性能:打包策略Fiber为什么要用FiberFiber 有什么益处原理为什么用Fiber,有什么益处之前的React的节点比对和更新,执行副作用是同步进行的,频繁调用会让浏览器没方法响应用户的键盘等事件,渲染时会有卡顿等景象。React做Fiber是为了能疾速响应用户,晋升用户体验。 React做的事件是让把同步更新改为两阶段,协调:比照节点,失去新的树,提交:更新。模仿原来的栈调度,反对工作的中断和复原。能够在中断时执行更高优先级的工作。 Fiber是什么,原理Fiber是协程的意思,实现了单干式调度,在浏览器闲暇的时候执行,工夫到了就让出,期待下一次调用。requestIdleCallback。Fiber也是一个执行单元,对原来的构造进行革新,革新成链表模式,用链表模仿递归调用栈。Fiber原理 HooksHooks是什么货色,为什么须要它Hooks原理React 加强了函数组件能力,次要有以下两个方面: 代码治理层面:简单组件互不关联的逻辑在一起,会变得难以了解。hooks相干的逻辑在一起,逻辑更清晰,加强了函数组件的能力。代码复用层面:React提倡的组件复用形式是组合,hooks呈现之前组件复用形式是两种: HOC 高阶函数:长处:加强模式,不会改变原组件,能够抽取共享的业务逻辑。毛病: 多层嵌套,下层解决不可见,不能用ref render props: function as a child长处: 共享状态和行为,因为传染组件,比拟灵便毛病:多个子组件嵌套天堂,可读性差不好保护 Hooks扁平,没有多层嵌套,更轻便的复用形式。Hooks原理原理是保护一个Hooks链表。组件的Fiber链表树中,每个组件保护hooks链表和指针,每次触发时程序执行一遍。Hooks原理 Redux用处: 跨父子组件通信共享数据管理益处:可追踪,单向数据流,没有副作用毛病:滥用会让组件变得难以保护,一些长期状态没必要放进去 React-redux:connect 原理,是一个高阶函数,把props和dispatch的action 挂在props, 订阅store 更新props,刷新组件。 React setState同步还是异步React 在更新/创立阶段时异步,合成事件内异步。原生绑定事件和定时器内同步。setState时依据一个变量判断判断是立刻更新还是丢到队列批量更新。 React事件// todo

March 11, 2021 · 1 min · jiezi

关于react.js:setState是同步的还是异步的

setState 只在合成事件和钩子函数中是“异步”的,在原生事件和 setTimeout 中都是同步的。合成事件:就是react 在组件中的onClick等都是属于它自定义的合成事件原生事件:比方通过addeventListener增加的,dom中的原生事件以下为同步拿到数据在setState中的回调函数中拿到 this.setState({ count: this.state.count + 1},()=>{ console.log(this.state.count)}) 在setTimeOut中拿到 setTimeout(()=>{ this.setState({count:this.state.count}) console.log(this.state.count) },0) 在原生事件中批改状态 state = { count:0};componentDidMount() { document.body.addEventListener('click', this.changeVal, false);}changeVal = () => { this.setState({ number: 1 }) console.log(this.state.count)}

March 11, 2021 · 1 min · jiezi

关于react.js:react手写useState

let _state=[];let index=0;function myUseState(initialValue) { int currentIndex=index; //引入两头变量currentIndex就是为了保留以后操作的下标index。 _state[currentIndex] = _state[currentIndex]===undefined? initialValue:_state[currentIndex]; const setState = (newValue) => { _state[currentIndex] = newValue; render(); }; index+=1;// 每次更新完state值后,index值+1 return [_state[currentIndex], setState];}const render = () => { index=0; //重要的一步,必须在渲染前后将index值重置为0,不然index会一种减少1 ReactDOM.render(<App />, document.getElementById("root"));};// 应用myUseStateconst App = () => { const [n, setN] = myUseState(0); const [m, setM] = myUseState(0); return ( <div classNam="App"> <p>n:{n}</p> <button onClick={()=>{setN(n+1)}}>n+1</button> <p>m:{m}</p> <button onClick={()=>{setM(m+1)}}>n+1</button> </div> );};ReactDOM.render(<App />, document.getElementById("root"));

March 4, 2021 · 1 min · jiezi

关于react.js:react和vue比较

vue和react都是做组件化的,针对view层,反对参数和state,有虚构dom机制,数据驱动视图。各自配套的全局数据存储vuex和redux也都是flux架构的实现,有action和state,数据变动会告诉组件。然而vue、vuex和react、redux还是有很多不同的 vue劣势包含:模板和渲染函数的弹性抉择简略的语法及我的项目创立更快的渲染速度和更小的体积react的劣势包含:更实用于大型利用和更好的可测试性同时实用于web端和原生app更大的生态圈带来的更多反对和工具vue和react相同之处包含:利用虚构DOM实现疾速渲染轻量级响应式组件服务器端渲染易于集成路由工具,打包工具以及状态管理工具优良的反对和社区为什么react比vue更适宜大型利用?vue的模板写法在组件数据较多时,数据和模板强相干,模板不能动静抽离为函数,而在react中,jsx能够很不便的抽离为函数,尽管vue也能够在render中写jsx,但在模板中无奈应用this高阶组件的写法上,react能够更好的应用,保护,vue中高阶组件大部分状况下时应用mixins,实现真正的高阶组件比拟麻烦或者说很难实现vue中的函数编程思维利用较少,大部分是基于对象的,而在大型项目中函数式会更加灵便

March 1, 2021 · 1 min · jiezi

关于react.js:如何在React中处理组件交互

每个React利用都是由交互组件组成的。这些组件如何通信是UI体系结构的一个重要一环。随着应用程序变得更大、更简单,组件交互变得更加重要。 React提供了多种办法来解决这种需要,每种办法都有其相应的用例。这次让咱们从最简略的亲子互动办法开始。 亲子与道具组件之间最简略的通信模式是通过属性——通常称为道具(Props)。Props是由父组件传递给子组件的参数,相似于函数的参数。 Props容许将变量传递给子节点,当值产生更改时,它们会在子节点中自动更新,如Listing 1所示。 Listing 1. Props (class-based): function App(){ return <div> <AppChild name="Matt" /> </div> } function AppChild(props){ return <span> My name is {props.name} </span> } ReactDOM.render(<App />, document.getElementById('app')); Listing 1显示了如何在基于函数的组件树中解决props。这个过程与类相似。这个基于函数的示例展现了函数款式的更精简的语法。 带性能道具的子-父组件Listing 1容许将值从父级传递给子级。当子节点须要更新父节点的变更时,它们不能仅批改属性。 如果你试图间接批改子过程的prop,你会在控制台中看到以下类型的谬误: Uncaught TypeError: Cannot assign to read only property 'foo' of object '#<Object>' 相同,父过程能够传入一个功能性道具,子过程能够调用这个函数。这种性能道具是一种面向事件的编程。您能够在Listing 2中看到这一点。 Listing 2. Functional props function App(){ const [name, setName] = React.useState("Matt"); return <div> <AppChild name={name} onChangeName={()=>{setName("John")}}/> </div> } function AppChild(props){ return <span> My name is {props.name} <button onClick={props.onChangeName}>Change Name</button> </span> } ReactDOM.render(<App />, document.getElementById('app')); Listing 2介绍了用于治理状态的useState。这是一个简略的机制。functional prop的实质是当按钮被点击时,App组件传入的函数就会被执行。这样,就实现了子-父通信。 总的来说,要记住的概念是:道具流向子级,事件流向父级。这是一个有价值的设计准则,有助于放弃应用程序的组织性和可管理性。 向父级传递信息通常状况下,子组件须要随它们的事件一起传递参数。这能够通过向函数道具回调增加参数来实现。如Listing 3所示。 function App(){ const [name, setName] = React.useState("Matt"); //test return <div> <AppChild name={name} onChangeName={(newName)=>{setName(newName)}}/> </div> } function AppChild(props){ return <span> My name is {props.name} <button onClick={()=>props.onChangeName("Bill")}>Change Name</button> </span> } ReactDOM.render(<App />, document.getElementById('app')); 留神 Listing 3中的 onClick={()=>props.onChangeName("Bill")}行。这里,咱们应用箭头语法创立一个匿名函数,其中蕴含咱们想要的参数。传递一个由组件自身批改的变量也很简略,语法如下:onClick={(myVar)=>prop . onchange (myVar)}。 顺便阐明一下,作为事件处理程序的内联箭头函数有时会因为性能问题而受到批评,只管这可能被言过其实。 性能道具和React Router另一个重要的用例是在 React Router 之间传递参数。Listing 4提供了如何实现这一点的示例。 Listing 4. Passing functional props through Router // In the route definition: <Route path=’/foopath’ render={(props) => <Child {…props} />} /> // In the child component: <Route appProps={{ onTitleChange }} /> 从实质上讲,Listing 4通过笼罩路由的出现形式容许间接传递属性。 同级沟通到目前为止,咱们看到的个性提供了解决同级通信的能力。这在React文档中被称为“晋升状态”。 这里的思维是,当组件树的同一级别的子组件必须共享状态时,该状态将被推入父组件。而后父级通过道具将状态分享给须要它的子级。子节点引发事件以更新父节点的状态,这将主动在共享属性中反映进去。 React Context APIReact自身提供的另一个选项是Context API。Context API被设计用来治理简略的、有全局意义的值。也就是说,这些值被应用程序中的许多组件应用。 文档中给出的示例是一个主题设置。许多组件将会对这种设置感兴趣(为了反映适当的主题),这与道具一起传递十分艰难。 Context API不用于解决简单的应用程序数据,它是专门针对在深度嵌套的组件中防止简单的道具解决的。Listing 5给出了一个简略的示例。 Listing 5. Context API // defining the context value <ThemeContext.Provider value="dark"> // Consuming the context value later on <Button theme={this.context} />; Redux的集中状态更简单的应用程序可能须要更简单的状态架构。在React中解决这个问题最常见的库依然是Redux。Redux不仅仅是一个集中式存储,它更是一个自以为是的结构化事件零碎。 Redux的核心思想是,组件通过称为dispatchers的非凡对象引发事件(在Redux中称为动作)。这些动作事件由reducer察看到,而后reducer将动作利用到状态。而后,视图中的组件会自动更新以反映状态。 从这段简短的形容能够看出,Redux为您的应用程序引入了相当多的复杂性和正式性。在应用Redux时,这应该与结构化和可了解性的益处进行审慎的均衡。 还有其余治理集中商店的办法,包含MobX等。只管这些解决方案可能比Redux有劣势,但必须衡量Redux的风行所带来的劣势,即相熟度和理解它的开发人员的可用性。 React通过props和function props提供了十分弱小和简略的组件交互。在更大,更简单的应用程序中,这种办法可能会解体。利用诸如Context API和Redux之类的更简单的选项能够解决这些更简单的需要。 ...

March 1, 2021 · 1 min · jiezi

关于react.js:react在哪些情况下调用thissetState会导致死循环

react在哪些状况下调用this.setState会导致死循环 1.componentWillUpdate 2.componentDidUpdate 3.render

March 1, 2021 · 1 min · jiezi

关于react.js:阿里笔试红绿灯-看到一篇文章后的随手记录

看到的文章链接如下https://mp.weixin.qq.com/s/8G... /** 1. 信号灯控制器用 React 实现一个信号灯(交通灯)控制器,要求:1. 默认状况下, 1.1. 红灯亮20秒,并且最初5秒闪动 1.2. 绿灯亮20秒,并且最初5秒闪动 1.3. 黄灯亮10秒 1.4. 秩序为 红-绿-黄-红-绿-黄2. 灯的个数、色彩、持续时间、闪动工夫、灯光秩序都可配置,如: lights=[{color: '#fff', duration: 10000, twinkleDuration: 5000}, ... ]*/import React from 'react'import ReactDOM from 'react-dom'class TrafficLightItem extends React.Component {}工夫还是挺紧的 有些写的比拟粗率twinkle成果没写 间接用css实现就好了 在twinkleState为true时 加闪动的款式 不小心写了个小Bug 坑了波本人 一共花了差不多1个小时写进去如下所有代码编辑红绿灯配置以及批改程序没写 临时只反对了通过input输出配置 能够轻易找个网站如https://codesandbox.io/s/93m5... 复制代码 查看成果 import React, { useState } from "react";import ReactDOM from "react-dom";class Control extends React.Component { constructor(props) { super(props); this.color = React.createRef(); this.duration = React.createRef(); this.twinkleDuration = React.createRef(); } state = { lightList: [], showTip: false }; handleLighgData = () => { let [c, d, twinkle] = this.getRefValue(); let isEmptyValue = this.isEmptyValue; if (isEmptyValue(c) || isEmptyValue(d) || isEmptyValue(twinkle)) { this.setState({ showTip: true }) return false; } let lightList = this.state.lightList; lightList.push({ color: c, duration: d, twinkle: twinkle }); this.setState({ lightList, showTip: false }); }; isEmptyValue = (value) => { return ( value === "" || value === null || value === false || value === void 0 ); }; getRefValue = () => { return [ this.color.current.value, this.duration.current.value, this.twinkleDuration.current.value ]; }; editLight = (index) => { //待实现 }; render() { const { lightList, showTip } = this.state; return ( <> <div> Color: <input ref={this.color} /> </div> <div> Duration: <input ref={this.duration} /> </div> <div> twinkleDuration: <input ref={this.twinkleDuration} /> </div> <input type="submit" onClick={this.handleLighgData} /> {showTip ? <span>每个参数都是必填的</span> : ""} {lightList.length > 0 && lightList.map((item, index) => { return ( <div key={item.color + index}> {item.color},{item.duration},{item.twinkleDuration} <span onClick={this.editLight.bind(this, index)}>Edit</span> </div> ); })} <TrafficLightItem lightList={lightList} /> </> ); }}class TrafficLightItem extends React.Component { state = { curLight: {}, curLightList: [], showLight: true, twinkleState: false }; startLight = () => { let { lightList } = this.props; if (lightList.length === 0) return false; if (this.state.curLightList.length > 0) return false; this.setState({ curLightList: lightList }, () => { this.handleLightTime(); }); }; handleLightTime = () => { let { curLight, curLightList } = this.state; if (curLightList.length === 0) return false; let state = null; if (curLight.color !== void 0) { state = curLight; } else { state = curLightList[0]; curLightList.shift(); this.setState({ curLightList }); } this.setState({ curLight: state }); if (state.duration !== 0) { setTimeout(() => { this.setState( { curLight: Object.assign(state, { duration: 0 }) }, () => { this.handleLightTime(); } ); }, state.duration); } else if (state.twinkleDuration !== 0) { this.setState({ twinkleState: true }); setTimeout(() => { this.setState({ curLight: {}, twinkleState: false }, () => { this.handleLightTime(); }); }, state.twinkleDuration); } }; render() { let { curLight, twinkleState } = this.state; return ( <> <hr /> <input type="button" value="start" onClick={this.startLight} /> <div style={{ width: 10, height: 10, borderRadius: "50%", border: "solod 1px #000", background: curLight.color }} > </div> </> ); }}const rootElement = document.getElementById("root");ReactDOM.render(<Control />, rootElement);

February 28, 2021 · 3 min · jiezi

关于react.js:react爬坑之路

DVA路由页面组件写在routes文件夹下且第一个字母大写结尾=>react组件都是以首字母大写结尾 //router.js+ import Products from './routes/Products';...+ <Route path="/products" exact component={Products} />

February 26, 2021 · 1 min · jiezi

关于react.js:使用react-electron-开发一个ai配音软件瞎搞系列

github开源地址 electron-audio-create =>> 应用 React + Electron 开发的 AI 配音软件 往年就业的时候原本打算做自媒体那种沙雕配音的,后果发现很多配音免费,而很多是手机端的,用起来不不便。就想能不能搞一搞,而后就去抓了抓包,废了点劲搞下来一些接口,而后正好react练下手。就有了这个我的项目(自媒体搞黄了,就算求了不玩了) 应用react脚手架create-react-app生成react页面,而后依照electron。不过这样启动须要先启动react我的项目,在启动electron我的项目,后果必定搜下react和electron怎么配合了。搜了半天发现一个好帖子 疾速开启 react+electron 利用,完满解决启动问题 解决react + electron的启动问题之后,剩下就是惯例react根底部署,总共就一个页面。 遇到的难点:第一次应用electron。想应用axios来作为http申请发送工具,然而遇到防盗链Referer,和跨域,我不晓得electron如何能批改chromium,解除跨域(因为国内大神:龙泉寺扫地僧,人家的miniblink是能够定制参数解除任何限度)。所以最初采纳electron自带的http申请做解决。能够批改Referer。 软件完工后如下:

February 26, 2021 · 1 min · jiezi

关于react.js:浅析-requestIdleCallback

本文同步公布在我的 Github博客 前言最近在钻研 React Fiber 相干的常识,上一篇文章 浅谈对 React Fiber 的了解 简略提到了 requestIdleCallback, React 源码中 polyfill 了这个办法,理解它对 Fiber 也能有进一步了解。本篇会深刻介绍下这个办法。 requestIdleCallback 是什么requestIdleCallback 是 window 属性上的办法,它的作用是在浏览器一帧的残余闲暇工夫内执行优先度绝对较低的工作。 为什么须要 requestIdleCallback在网页运行中,有很多耗时但又不是那么重要的工作。这些工作和重要的工作如对用户的输出作出及时响应的之类的工作,它们共享事件队列。如果两者发生冲突,用户体验会很蹩脚。 requestIdleCallback 就解决了这个痛点,requestIdleCallback 会在每一帧完结时并且有闲暇工夫执行回调。 假如须要大量波及到 DOM 的操作的计算,在运算时,浏览器可能就会呈现显著的卡顿行为,甚至不能进行任何操作,因为是 JS 单线程,就算用在输出解决,给定帧渲染和合成之后,用户的主线程就会变得闲暇,直到下一帧的开始。 而这些闲暇工夫能够拿来解决低优先级的工作,React16 的调度策略异步可中断,其中要害就靠的这个(polyfill)办法性能;React 把工作细分(工夫切片),在浏览器闲暇的工夫去执行,从而尽可能地进步渲染性能。 工夫切片的实质是模仿实现 requestIdleCallback 讲到这里,从 React15 到 React16 Fiber,对整体性能来说是大优化了;但要晓得的是,React16 绝对 15 做出的优化,并不是大大减少了任务量,你写的代码的工作总量并没有变动,只是把闲暇工夫利用起来了,不停的干活,就能更快的把活干完;这只是其中一个角度,React 还做了辨别优先级执行等等。 屏幕刷新率和 FPS 的关系以后大多数的屏幕刷新率都是 60HZ,一秒 60 帧(FPS 为 60),也就是每秒屏幕刷新 60 次,此时一帧的工夫为 16.7ms(1000ms/60)低于 60HZ 人眼就会感知卡顿掉帧等状况。 浏览器的一帧说的就是一次残缺的重绘。前端浏览器所说的渲染频率 FPS(Frames Per Second)是每秒传输帧数,即是每秒刷新的次数,实践上 FPS 越高人眼感觉界面越晦涩。 window.requestIdleCallback() 用法window.requestIdleCallback()办法将在浏览器的闲暇时段内调用的函数排队。这使开发者可能在主事件循环上执行后盾和低优先级工作,而不会影响提早要害事件,如动画和输出响应。函数个别会按先进先调用的程序执行,然而,如果回调函数指定了执行超时工夫 timeout,则有可能为了在超时前执行函数而打乱执行程序。 ...

February 25, 2021 · 2 min · jiezi

关于react.js:animate-js-文字跑马灯

写一个跑马灯,css的animate import React, { PureComponent } from 'react';import "./index.css";// 跑马灯const speed = 20let marquee_id = 1class Marquee extends PureComponent { constructor (props) { super(props) this.viewRef = React.createRef() this.textRef = React.createRef() } move (start, end, durition) { ++marquee_id this.viewRef.style = ` animation: move_${marquee_id} ${durition}s linear infinite; ` var styleSheets = document.styleSheets[0]; //获取样式表援用 var index = styleSheets.length; //获取样式表中蕴含款式的个数 if(styleSheets.insertRule){ //判断浏览器是否反对insertRule()办法 styleSheets.insertRule(`@keyframes move_${marquee_id} { from { transform: translateX(${start}px); } to { transform: translateX(${end}px); } }`, index); } } componentDidMount () { const viewWidth = this.viewRef.getBoundingClientRect().width const textWidth = this.textRef.getBoundingClientRect().width const durition = Math.floor(textWidth / speed) if (textWidth > viewWidth) { const start = viewWidth const end = -Math.floor(textWidth) this.move(start, end, durition) } } componentDidUpdate () { const viewWidth = this.viewRef.getBoundingClientRect().width const textWidth = this.textRef.getBoundingClientRect().width const durition = Math.floor(textWidth / speed) if (textWidth > viewWidth) { const start = viewWidth const end = -Math.floor(textWidth) this.move(start, end, durition) } } render() { const { text } = this.props return ( <div className="Marquee_Bar"> <div className="Marquee_View" ref={ref => this.viewRef = ref}>{ text }</div> <div className="Marquee_Opacity" ref={ref => this.textRef = ref}>{ text }</div> </div> ); }}export default Marquee;css局部 ...

February 22, 2021 · 1 min · jiezi

关于react.js:mobx-有bug-的-todolist-待修改

import React, { Component, useEffect } from 'react';import './App.css';import { observable, computed, action } from 'mobx';import { observer,Provider,inject } from 'mobx-react' //数据结构class Todo { @observable todos = [ { id: 1, title: '工作1', finished: true }, { id: 2, title: '工作2', finished: false }];@computed get unfinishedTodoCount() { return this.todos.filter(todo => !todo.finished).length;}@action delTodo(id) { console.log('删除'); this.todos = this.todos.filter(todo => todo.id !== id); console.log(this.todocs);}@action updateTodo(id,done) { console.log('update'); const newTodos = this.todos.map((todoObj)=>{ if(todoObj.id === id) return {...todoObj,done} else return todoObj }) this.todos = newTodos;}} ...

February 22, 2021 · 1 min · jiezi

关于react.js:React-Context用法总结

Context作用React中,父子组件通信的机制,父子组件的通信是通过props进行数据的传递。Context提供了一种形式,可能让数据逾越组件层级来传递,不再须要一层一层的传递 如何应用React.createContext() const MyContext = React.createContext(defaultValue) defaultValue 默认值,没有Provider时会失效Context.Provider<MyContext.Provider value={/* 某个值 */}>Provider 接管一个 value 属性,传递给生产组件Class.contextType能够通过Class.contextType间接将Context对象挂载到class的contextType属性,而后就能够应用this.context对context对象进行应用 class MyClass extends React.Component { render() { let value = this.context; /* 基于 MyContext 组件的值进行渲染 */ }}MyClass.contextType = MyContext;或class MyClass extends React.Component { static contextType = MyContext; render() { let value = this.context; /* 基于这个值进行渲染工作 */ }}Context.Consumer<MyContext.Consumer> {value => /* 基于 context 值进行渲染*/}</MyContext.Consumer>置信小伙伴对 React context 的作用 以及应用有了肯定的理解。当然还有其余场景的应用,可间接看官网(https://react.docschina.org/d...)也心愿帮忙到须要的小伙伴们。

February 20, 2021 · 1 min · jiezi

关于react.js:react相关的3个面试题

react相干的3个面试题setState是同步还是异步?legacy模式,命中batchedUpdates时是异步legacy模式,未命中batchedUpdates时是同步 比方:用setTimeout包裹setState函数concurrent模式都是异步legacy模式 -- ReactDOM.render(<App />, rootNode) concurrent模式 -- ReactDOM.createRoot(rootNode).render(<App />) react的申明周期函数标红的是行将过期,应该防止应用他们 useEffect(fn, [ ])和componentDidMount有什么区别聊聊useEffect的第二个参数如何影响useEffect回调函数的执行useEffect回调函数与componentDidMount的执行机会 useEffect(fn, []) -- commit阶段实现后异步调用componentDidMount -- commit阶段实现视图更新(mutation阶段)后,在layout阶段同步调用useLayoutEffect(fn, []) -- 在layout阶段同步调用,跟componentDidMount的的调用机会统一

February 19, 2021 · 1 min · jiezi

关于react.js:在react项目中按需引入antd

步骤(次要参照官网流程) 装置antd: yarn add antd在页面中应用组件 import { Button } from 'antd';export default () => { return (<Button type="primary">Primary</Button>)}踩坑 引入后无款式解决:在src/index.js 中增加 import 'antd/dist/antd.css';

February 18, 2021 · 1 min · jiezi

关于react.js:react组件跨层通信-笔记

react组件跨层通信 笔记组件与组件之间的关系,大抵可分为 4 种。父与子:父组件包裹子组件,父组件向子组件传递数据。子与父:子组件存在于父组件之中,子组件须要向父组件传递数据。兄弟:两个组件并列存在于父组件中,须要金属数据进行互相传递。无间接关系:两个组件并没有间接的关联关系,处在一棵树中相距甚远的地位,但须要共享、传递数据。通信形式总结如下: 父与子父与子的通信次要是通过props。React 开发的每个组件都在应用这样的设计模式。每个组件都会在父级被应用,再传入 Props,实现信息的传递。这样的交互方式只管不起眼,容易让人疏忽,但正是最经典的设计。 子与父子与父的通信次要依赖回调函数。 回调函数回调函数在 JavaScript 中称为 callback。React 在设计中沿用了 JavaScript 的经典设计,容许函数作为参数赋值给子组件。最根底的用法就像上面的例子一样,通过包装传递 text 的值。 class Child  extends React.Component { handleChanged = (e) => { //调用父组件传进来的回调函数 this.props.onChangeText(e.target.text) } render() { return <input onChange={handleTextChanged} /> }}class Father extends React.Component { handleTextChanged = (text) => { console.log(text) } render() { return ( // 把函数当做props参数传给子组件 <Child onChangeText={this.handleTextChanged} /> ) }}实例函数须要留神的是,实例函数是一种不被举荐的应用形式。这种通信形式常见于 React 风行初期,那时有很多组件都通过封装 jQuery 插件生成。最常见的一种状况是在 Modal 中应用这种形式。如下代码所示: import React from 'react'class HomePage extends React.Component { modalRef = React.createRef() showModal = () ={ this.modalRef.show() } hideModal = () => { //通过ref获取到的实例操作,不过当初个别都不这么用了,当初会给一个参数show=true或show=false来管制组件显示或者暗藏 this.modalRef.hide(); } render() { const { text } = this.state return ( <> <Button onClick={this.showModal}>展现 Modal </Button> <Button onClick={this.hideModal}>暗藏 Modal </Button> <Modal ref={modalRef} /> </> /> ) }兄弟兄弟组件之间的通信,往往依赖独特的父组件进行直达。也就是状态晋升。 ...

February 14, 2021 · 3 min · jiezi

关于react.js:react实践总结

写react也有一段时间了,之前是vue,去年转成react,刚开始的确有点不习惯,经验了一些我的项目的锻炼,当初开始缓缓喜爱上了react。同时,也在一直的实际中,开始总结一些好的办法,当然是集体认为的一些好习惯,每个人都有每个人的认识,欢送交换。 优先应用function组件如果能够的话,尽可能应用function组件,缩小应用class组件,加上当初hook的大风行,基本上大部分场景都能够应用function搞定,遗记class的生命周期,constructor吧。比方以前都是这样写 而当初,你能够这样写 是不是十分简洁明了,写更少的代码,实现雷同的事件。 尽量为你的组件命名这样能够减少代码可读性,也不便在debug的时候排查谬误。 // bad caseexport default () => <div>...</div>// good caseexport default function User() { return <div>...</div>}正当组织公共办法如果你的function组件须要用到一些比方解决数据、日期的办法,请将其放到function组件里面,一方面放弃function的简洁,一方面能够便于在别的中央重用这些办法。当然这些办法也能够对立放到utils外面去,决定权在你。 // bad casefunction Calendar({ date }) { function parseDate(date) { ... } return <div>Today is {parseDate(date)}</div>}// good casefunction parseDate(date) { ...}function Calendar({ date }) { return <div>Today is {parseDate(date)}</div>}善用map、filters等办法比方须要展现一个人的兴趣爱好列表,并进行相干操作等 // bad casefunction Filters({ onFilterClick }) { return ( <> <ul> <li> <div onClick={() => onFilterClick('travel')}>游览</div> </li> <li> <div onClick={() => onFilterClick('music')}> 听音乐 </div> </li> <li> <div onClick={() => onFilterClick('movies')}>看电影</div> </li> </ul> </> )}// good caseconst List = [ { identifier: 'travel', name: '游览', }, { identifier: 'music', name: '听音乐', }, { identifier: 'movies', name: '看电影', }]function Filters({ onFilterClick }) { return ( <> <ul> {List.map(item => ( <li> <div onClick={() => onFilterClick(item.identifier)}> {genre.name} </div> </li> ))} </ul> </> )}留神单个组件代码量尽可能放弃单个组件代码行数管制在肯定范畴内,单个组件实现单个组件的工作,不要柔和在一起,写一个几千行的组件,当然这是个人见解,这个仁者见仁,最好不要太多,太多的话阐明拆分粒度不够,也不不便他人code review代码。 ...

February 14, 2021 · 2 min · jiezi

关于react.js:如何实现一个批量获取数据的dataloader合并多个操作

写在后面,dataloader代码曾经很少了,只有三百行而且一半是正文。然而我就是想写 /** *一个承受 ids 而后返回后果的函数handle, * 对这个handle进行封装,返回一个loader * 每次通过调用loader来调用handle * 每接管到一个对loader的调用 * 就存储起来,并不立刻执行handle * 而是收集loader的参数id,并且将多个id合并为ids * 最初在js执行的开端,调用一次handle(ids)这样 * * @export * @param {(id: number) => {}} handle */export default function Dataloader<T>(handle: (ids: number[]) => Promise<T[]>) { const cachesMap = {}; const loader = { cacheIdsQue: [] as {id: number; resolve: Function; reject: Function}[], load: function (id: number) { const quePromise = new Promise((resolve, reject) => { this.cacheIdsQue.push({ id, resolve, reject }); if (this.cacheIdsQue.length === 1) { this.nextTickRun(); } }) return quePromise; }, nextTickRun() { Promise.resolve().then(() => { if (this.cacheIdsQue.length) { const cacheIdsQue = this.cacheIdsQue; const results = handle(this.cacheIdsQue.map(ref => ref.id)); results.then((values) => { values.forEach((element, index) => { cacheIdsQue[index].resolve(element); }); this.clearQue(); }) } }); }, clearQue() { this.cacheIdsQue = []; } } return loader;}// 测试const loader = new Dataloader((ids) => { return Promise.resolve(ids.map(id => { return id + 'abc'; }));});loader.load(3).then(console.log)loader.load(1).then(console.log)loader.load(2).then(console.log)

February 8, 2021 · 1 min · jiezi

关于react.js:React-组件通信之发布订阅模式

React 通信react的数据流是单向的, react 通信有以下几种形式: 父向子通信: 传入props子向父通信:父组件向子组件传一个函数,而后通过这个函数的回调,拿到子组件传过来的值父向孙通信:利用context传值。React.createContext()兄弟间通信: 1、找一个雷同的父组件,既能够用props传递数据,也能够用context的形式来传递数据。 2、用一些全局机制去实现通信,比方redux等 3、公布订阅模式 兄弟间通信 - 公布订阅模式组件间通信须要援用一个类的实例,应用单例模式实现。 公布/订阅模式在 公布/订阅模式 有 发布者 和 订阅者,它们通过信道链接到一起。 其次要蕴含三个对象: 发布者:音讯的发布者,往信道中投递音讯的对象。订阅者:订阅一个或者多个信道音讯的对象。信道:每个信道都有一个名字,信道的实现细节对用户代码来说是暗藏的。长处 松耦合:发布者和订阅者的通信是在用户代码之外解决的,通过信道升高了发布者和订阅者的耦合性可扩展性:公布/订阅模式能够让零碎在无论什么时候都能够扩大灵活性:不须要放心不同的组件是如何组合在一起的毛病 无奈晓得音讯传送是胜利的还是失败的,信道不会告诉零碎音讯传送的状态随着订阅者和发布者数量的减少,一直减少的音讯传送回导致架构的不稳固,容易在负载大的时候出问题单例模式确保一个类仅有一个实例,并提供一个拜访它的全局拜访点。 代码实现定义公布对象: class SingletonPublish { constructor() { this.listenList = {}; this.instance = null; } static getInstance() { if (!this.instance) { this.instance = new SingletonPublish(); } return this.instance; } // 订阅者增加订阅事件 addListen(key, fn) { if (!this.listenList[key]) { this.listenList[key] = []; } this.listenList[key].push(fn); } // 发布者公布音讯,执行订阅者订阅事件 trigger() { const key = Array.from(arguments).shift(); const fns = this.listenList[key]; if (!fns || fns.length === 0) { return false; } fns.forEach((fn) => { fn.apply(this, arguments); }); } // 移除订阅事件 remove(key, fn) { const fns = this.listenList[key]; if (!fns || fns.length === 0) return; if (!fn) { this.listenList[key] = []; } else { for (let l = fns.length - 1; l >= 0; l--) { if (fn === fns[l]) { fns.splice(l, 1); } } } }}export default SingletonPublish.getInstance();订阅者订阅一个back事件: ...

February 8, 2021 · 1 min · jiezi

关于react.js:终于知道react和dataloader是怎么合并操作的了-setState

终于晓得了,没想到这么简略。以前的纳闷就是,里面疯狂setState,setState本身怎么晓得以后调用是最初一次调用了,这之后我就应该执行真正的赋值操作。 其实基本就不须要晓得,而是这样的,参考:https://zhuanlan.zhihu.com/p/... function enqueueSetState( stateChange, component ) { // 如果queue的长度是0,也就是在上次flush执行之后第一次往队列里增加 if ( queue.length === 0 ) { defer( flush ); } queue.push( { stateChange, component } ); if ( !renderQueue.some( item => item === component ) ) { renderQueue.push( component ); }}这第一次调用的时候,就申明了,我须要异步的执行真正的更新操作。这样,所有的同步的调用push完了之后他就会立即调用更新操作。切实没想到会这么简略,亏我想破了脑袋

February 7, 2021 · 1 min · jiezi

关于react.js:reactrouterdom-中文文档

HOOKSReact Router附带了一些HOOK,可让您拜访路由器的状态并从组件外部执行导航 useHistoryuseLocationuseParamsuseRouteMatchuseHistoryuseHistory 钩子返回 history 对象,能够应用 useHistory 进行导航 import { useHistory } from "react-router-dom";function HomeButton() { let history = useHistory(); function handleClick() { history.push("/home"); } return ( <button type="button" onClick={handleClick}> Go home </button> );}useLocationuseLocation 钩子返回以后URL的 location 对象。能够把它设想成一个useState,每当URL发生变化时,它都会返回一个新的地位。 这是十分有用的,例如,当一个新的页面加载时,比方应用web剖析工具触发一个新的“页面视图”事件,如上面的例子所示: import React from "react";import ReactDOM from "react-dom";import { BrowserRouter as Router, Switch, useLocation} from "react-router-dom";function usePageViews() { let location = useLocation(); React.useEffect(() => { ga.send(["pageview", location.pathname]); }, [location]);}function App() { usePageViews(); return <Switch>...</Switch>;}ReactDOM.render( <Router> <App /> </Router>, node);useParamsuseParams 动静参数列表的援用对象,用于获取<Route>中的 match.params (动静参数) ...

February 7, 2021 · 9 min · jiezi

关于react.js:浅谈对-React-Fiber-的理解

前言本文作为本人深刻学习 React Fiber (Reactv16.8.6)的了解,本篇仅介绍大抵流程,Fiber 具体源码本文不作细节形容。 本文同步公布在我的 Github 集体博客 Fiber 呈现的背景首先要晓得的是,JavaScript 引擎和页面渲染引擎两个线程是互斥的,当其中一个线程执行时,另一个线程只能挂起期待。 在这样的机制下,如果 JavaScript 线程长时间地占用了主线程,那么渲染层面的更新就不得不长时间地期待,界面长时间不更新,会导致页面响应度变差,用户可能会感觉到卡顿。 而这正是 React 15 的 Stack Reconciler 所面临的问题,即是 JavaScript 对主线程的超时占用问题。Stack Reconciler 是一个同步的递归过程,应用的是 JavaScript 引擎本身的函数调用栈,它会始终执行到栈空为止,所以当 React 在渲染组件时,从开始到渲染实现整个过程是零打碎敲的。如果渲染的组件比拟宏大,js 执行会占据主线程较长时间,会导致页面响应度变差。 而且所有的工作都是依照先后顺序,没有辨别优先级,这样就会导致优先级比拟高的工作无奈被优先执行。 Fiber 是什么Fiber 的中文翻译叫纤程,与过程、线程同为程序执行过程,Fiber 就是比线程还要细微的一个过程。纤程意在对渲染过程实现进行更加精密的管制。 从架构角度来看,Fiber 是对 React 外围算法(即和谐过程)的重写。 从编码角度来看,Fiber 是 React 外部所定义的一种数据结构,它是 Fiber 树结构的节点单位,也就是 React 16 新架构下的"虚构 DOM"。 一个 fiber 就是一个 JavaScript 对象,Fiber 的数据结构如下: type Fiber = { // 用于标记fiber的WorkTag类型,次要示意以后fiber代表的组件类型如FunctionComponent、ClassComponent等 tag: WorkTag, // ReactElement外面的key key: null | string, // ReactElement.type,调用`createElement`的第一个参数 elementType: any, // The resolved function/class/ associated with this fiber. // 示意以后代表的节点类型 type: any, // 示意以后FiberNode对应的element组件实例 stateNode: any, // 指向他在Fiber节点树中的`parent`,用来在解决完这个节点之后向上返回 return: Fiber | null, // 指向本人的第一个子节点 child: Fiber | null, // 指向本人的兄弟构造,兄弟节点的return指向同一个父节点 sibling: Fiber | null, index: number, ref: null | (((handle: mixed) => void) & { _stringRef: ?string }) | RefObject, // 以后处理过程中的组件props对象 pendingProps: any, // 上一次渲染实现之后的props memoizedProps: any, // 该Fiber对应的组件产生的Update会寄存在这个队列外面 updateQueue: UpdateQueue<any> | null, // 上一次渲染的时候的state memoizedState: any, // 一个列表,寄存这个Fiber依赖的context firstContextDependency: ContextDependency<mixed> | null, mode: TypeOfMode, // Effect // 用来记录Side Effect effectTag: SideEffectTag, // 单链表用来疾速查找下一个side effect nextEffect: Fiber | null, // 子树中第一个side effect firstEffect: Fiber | null, // 子树中最初一个side effect lastEffect: Fiber | null, // 代表工作在将来的哪个工夫点应该被实现,之后版本改名为 lanes expirationTime: ExpirationTime, // 疾速确定子树中是否有不在期待的变动 childExpirationTime: ExpirationTime, // fiber的版本池,即记录fiber更新过程,便于复原 alternate: Fiber | null,}在 2020 年 5 月,以 expirationTime 属性为代表的优先级模型被 lanes 取代。Fiber 如何解决问题的Fiber 把一个渲染工作合成为多个渲染工作,而不是一次性实现,把每一个宰割得很细的工作视作一个"执行单元",React 就会查看当初还剩多少工夫,如果没有工夫就将控制权让进来,故工作会被扩散到多个帧外面,两头能够返回至主过程管制执行其余工作,最终实现更晦涩的用户体验。 ...

February 7, 2021 · 4 min · jiezi

关于react.js:扔掉你的Class吧Hooks太香了一

简介Hook 是React16.8中新增的个性,它能够让你不编写class组件的状况下应用诸如state,生命周期等个性。 动机在组件之间复用状态逻辑很难为了解决这类问题,也有呈现过一些解决方案,如render props、高阶组件、Context等,它们都会导致组件树造成嵌套天堂(有点像回调函数和flutter的写法)。 有了 Hook 之后,就能够从组件中提取状态逻辑,使得这些逻辑能够独自测试并复用。Hook 使你在无需批改组件构造的状况下复用状态逻辑。 简单组件变得难以了解随着业务扩张,组件内的逻辑状态和副作用也越来越多。咱们在写 class 组件时,通常会将数据的获取放到compoentDidMount和componentDidUpdate中,波及到定时器或者数据订阅时,还须要在生命周期函数compoentWillUnmount去革除定时器或者勾销数据订阅。这使得齐全不相干的代码组合到一起,很容易产生bug,并且导致逻辑不清晰。 为了解决这个问题,Hook 将组件中互相关联的局部拆分成更小的函数(比方设置订阅或申请数据),而并非强制依照生命周期划分。 难以了解的 class在之前,如果你要应用诸如state、生命周期等个性,就必须引入 class 组件,如果你要应用这些就必须花工夫去了解 JavaScript 中this的工作形式。 为了解决这些问题,Hook 使你在非 class 的状况下能够应用更多的 React 个性。 概览Hook 能够分为内置 Hook和自定义 Hook。 内置 Hook 有: useStateuseEffectuseContextuseReduceruseCallbackuseMomeuseRefuseImperativeHandleuseLayoutEffectuseDebugValue自定义 Hook就是将上述内置 Hook进行组合,导出为一个以use结尾的函数。 这里先写一个基于class的 Counter组件,前面让咱们来用Hook将它进行革新。 `import React from 'react'class Counter extends React.Component {  constructor(props) {    super(props)    this.state = { count: 0 }    this.setCount = this.setCount.bind(this)  }  setCount() {    this.setState({      count: this.state.count + 1    })  }    render() {    return (      <>        <h2>{ this.state.count }</h2>        <button onClick={ this.setCount }>+</button>      </>    )  }}` useState让咱们先来看一个最根底也同样重要的 Hook,当初咱们开始革新下面的class组件。首先将class组件转为function组件,也就是函数式组件。`- class Counter extends React.Component {}+ function Counter() {}` 接下来让咱们将state等相干代码删掉,改用useStateHook,因为此处改变较多,间接上最终代码`import React, { useState } from 'react'const Counter = () => {  // 数组解构语法  // 申明一个count变量,并申明一个setCount函数用于扭转count的值  const [count, setCount] = useState(0)    return (    <>      <h2>{ count }</h2>      <button onClick={ () => setCount(count + 1) }>+</button>    </>  )}` 乍一看代码简洁了很多,这难道不正是咱们想要的嘛。(Hook 真香) 如果咱们有多个state变量,能够写成上面这种模式`const [count, setCount] = useState(0)const [num, setNum] = useState(0)const [name, setName] = useState('')...` 如果本次更新依赖于上一次的state值,能够这么写,此时setCount接管一个函数作为参数`const [count, setCount] = useState(0)const handleClick = () => {  setCount(prev => prev + 1)}<button onClick={ handleClick }>+</button>` useEffectuseEffect 能够让你在函数式组件执行一些副作用操作,它接管两个参数,第一个参数为必选的副作用函数,第二个为可选的参数(它是副作用函数执行的依赖项数组)还是方才的例子,如果咱们心愿组件更新后执行一些副作用,比方打印以后count变量的值,又或者扭转以后页面的 title ``// ...const [count, setCount] = useState(0)const [num, setNum] = useState(0)useEffect(() => {  console.log(以后count值,${count})  document.title = 以后count值,${count}})// ...`` 下面的代码咱们能够看到咱们并没有增加第二个可选参数,这意味着,只有组件内状态产生扭转(不仅仅是count,甚至num产生扭转时),这个副作用函数都会执行。如果咱们心愿副作用函数只在 count 扭转时候执行,这时候咱们的第二个参数就派上用场了()``// ...// 以后effect函数只依赖于 count 的扭转,在 num 扭转的时候并不会被执行// 相当于 class 组件中的 compoentDidMount 和 componentDidUpdateuseEffect(() => {  console.log(以后count值,${count})  document.title = 以后count值,${count}}, [count])// ...`` 如果咱们仅仅心愿副作用函数在组件挂载时候执行(compoentDidMount)``// useEffect 约定,在第二个参数传递空数组时,以后副作用函数只在组件挂载时被执行useEffect(() => {  console.log(以后count值,${count})  document.title = 以后count值,${count}}, [])`` 有些时候咱们可能会用到定时器,比方每秒钟更新一次工夫`const [time, setTime] = useState(new Date())const timer = nulluseEffect(() => {  timer = setInterval(() => {    setTime(new Date())  }, 1000)})` 当初的代码有一个问题,想必大家都晓得,那就是timer 没有被革除,咱们在工作中会遇到很多这种场景,那么咱们应该怎么去革除 timer 呢,答案是useEffect的第一个参数返回一个函数,这个被返回的函数会在组件被卸载时候主动被执行,能够革除诸如定时器之类的货色`const [time, setTime] = useState(new Date())const timer = nulluseEffect(() => {  timer = setInterval(() => {    setTime(new Date())  }, 1000)    // 相似于 compoentWillUnMount    // 当然这里也能够是一个具名函数  return () => {    clearInterval(timer)    timer = null  }})`

February 5, 2021 · 1 min · jiezi

关于react.js:react-hook小记持续更新

很久以前看到react hook的时候,因为我的项目中没有应用过,所以也就没有很器重,对它也就是理解的状态.当初再看,有了一些小的了解,记录一下. const [name, setName] = useState('Mary');也能够是const [name, banana] = useState('Mary');一样能够失常应用,即批改state的办法能够是任意名称 之前我认为useState和useEffect是配对的,只能这么写:const [name, setName] = useState('Mary');useEffect(function persistForm() { localStorage.setItem('formData', name);});const [surname, setSurname] = useState('Poppins');useEffect(function updateTitle() { document.title = name + ' ' + surname;});就是useState前面必须有一个useEffect,但其实也能够这样写: const [name, setName] = useState('Mary');const [surname, setSurname] = useState('Poppins'); useEffect(function persistForm() { localStorage.setItem('formData', name);});useEffect(function updateTitle() { document.title = name + ' ' + surname;});useEffec并非肯定要跟在配对的useState的前面,那种写法是为了直观一点.useEffect会顺次调用,比方调用setName,两个useEffect都会执行的,只不过第二个值不会扭转

February 3, 2021 · 1 min · jiezi

关于react.js:React使用装饰器

create-react-app默认不反对装璜器的,须要做以下配置。关上 package.json ,能够看到eject。运行 npm run eject 能够让由create-react-app创立的我的项目的配置项裸露进去。 装置babel插件 Babel >= 7.xnpm install --save-dev @babel/plugin-proposal-decorators Babel@6.x npm install --save-dev babel-plugin-transform-decorators-legacy 批改package.json文件的babel配置项 Babel >= 7.x "babel": { "plugins": [ ["@babel/plugin-proposal-decorators", { "legacy": true }] ], "presets": [ "react-app" ] } Babel@6.x "babel": { "plugins": [ "transform-decorators-legacy" ], "presets": [ "react-app" ] }至此,就能够在我的项目中应用装璜器了 @MyContainerclass B extends Component{ render(){ return ( <p>B组件</p> ) }}export default B;

February 2, 2021 · 1 min · jiezi

关于react.js:Ant-Design中使用Upload上传组件如何自定义文件列表展示位置

软件环境macOS Big Sur 11.1React 16.12.0Ant Design 4.10.0实际效果现有一个需要,是上传文件,点击浏览文件按钮,选中文件后,在按钮的上方显示,上传的文件列表,如下图所示 以后成果目前应用阿里的Ant UI组件库,应用其中的上传组件,官网提供的示例,如下图如示 本地应用后,如下图所示 如何能力实现,咱们须要的成果呢,Google了好多文章,找到了一种形式,就是重写itemRender办法,自定义文件列表的展现,应用这个办法,须要重写多个action。 起初查看公司前端人员写的代码,看到另一种解决办法。 次要应用两个Upload组件,第一个Upload组件次要是展现文件列表,第二个Upload组件是抉择文件上传的这个操作,不过,抉择文件后,把文件列表在下方展现暗藏起来。 showUploadList: false, //不显示上传的列表把失去的文件列表,赋值给第一个Upload组件中,大略如下: beforeUpload(file: any, fileList: any) { setFileList(fileList); //设置文件列表 return false; //不要调用上传文件接口 },<!--第一个Upload组件--><Upload fileList={fileList}></Upload>局部代码如下: <StyleContent> <StyleMainContent> <Button onClick={btnOnClick} type="primary">关上上传</Button> <Modal visible={isVisible} title="上传附件" footer={[]} closable> <div style={{ border: '1px solid #ccc', height: 150, marginBottom: 10 }}> <Upload fileList={fileList} onChange={onChange}></Upload> </div> <div style={{ textAlign: 'right' }}> <Upload {...updateProps} ><Button type="primary">浏览文件</Button></Upload> <Button style={{marginLeft:2}} onClick={() => { setIsVisible(false) }}>敞开</Button> </div> </Modal> </StyleMainContent></StyleContent> const [isVisible, setIsVisible] = useState(false); const [fileList, setFileList] = useState([]); const btnOnClick = () => { setIsVisible(true); } const updateProps = { name: 'file', beforeUpload(file: any, fileList: any) { setFileList(fileList); return false; }, showUploadList: false, styly: { display: 'inline-block' } } const onChange = ({ file, fileList }: { file: any; fileList: any }) => { console.log(file, fileList); setFileList(fileList); };

February 1, 2021 · 1 min · jiezi

关于react.js:GGEditor踩坑记录不推荐

需要:应用react实现相似如下的可视化画拓扑图的界面 剖析能够看出次要性能点有1.可视化拖拽组件2.绘制节点和门路 经查阅,找到了与需要非常靠近的组件 GGEditor这是由阿里的一位大佬写的开源的可视化图编辑器,能够实现绘制节点和门路的性能,反对罕用快捷键,如ctrl+c,ctrl+v,delete等,成果如下图:demo地址 应用简略地介绍完须要的库后,开始应用。 1.创立一个名为demo的react我的项目,为了不便,我将应用typescript语言 npx create-react-app demo --typescript2.装置GGEditor npm install gg-editor --save3.为了不便开发,能够应用热更新插件react-refresh,参考此处4.首先,删除demo/src目录下不必要的文件5.画流程图index.js import React from 'react';import ReactDOM from 'react-dom';import GGEditor, {Flow} from 'gg-editor';//数据const data = { nodes: [ { id: '0', label: '点1', x: 55, y: 55, }, { id: '1', label: '点2', x: 55, y: 255, }, ], edges: [ { label: '边1', source: '0', target: '1', }, ],};class App extends React.Component { render() { return ( <GGEditor> <Flow style={{ width: 500, height: 500 }} data={data} /> </GGEditor> ); }}ReactDOM.render(<App />, document.getElementById('root'));6.带命令工具栏 ...

February 1, 2021 · 3 min · jiezi

关于react.js:React-生命周期小结

在这篇文章中,我会介绍 React 各个生命周期在理论我的项目中的利用场景,并给出代码示例。React 生命周期图谱:https://projects.wojtekmaj.pl... 挂载阶段(Mounting)组件实例创立并插入到 DOM 中。这个阶段调用生命周期函数程序顺次是: coustructor()、static getDerivedStateFromProps()、render()、componentDidMount()。 更新阶段(Updating)组件的 state 或者 props 发生变化时会触发更新。这个阶段调用生命周期函数程序顺次是:static getDerivedStateFromProps()、shouldComponentUpdate()、render()、getSnapshotBeforeUpdate()、componentDidUpdate()。 卸载阶段(UnMounting)组件从 DOM 中移除时,会调用 componentWillUnmount() 办法。 错误处理(Error boundaries)当渲染过程,生命周期,或子组件的构造函数中抛出谬误时,会调用如下办法:static getDerivedStateFromError()、componentDidCatch()。 render()留神⚠️:render() 函数是 class 组件中惟一必须实现的办法;render 函数的返回值:React 元素、数组、Fragments、Portals、字符串或数值、布尔值或 null;render 应为纯函数,并且不会与浏览器产生交互,这样使组件更加容易了解。constructor(props)调用工夫:React 组件在挂载之前,会调用它的构造函数。 应用场景:初始化 state给事件处理函数绑定实例class Test extends React.Component { constructor(props) { super(props); this.state = { counter: 0 }; this.handleClick = this.handleClick.bind(this); } handleClick() { const { counter } = this.state; this.setState({ counter: counter + 1 }); } render() { return ( <div> {this.state.counter} <button onClick={this.handleClick}>click</button> </div> ); }}ReactDOM.render( <Test />, document.getElementById('root'));留神⚠️:不要在构造函数中调用 setState 办法;在为 React.Component 子类实现构造函数时,应在其余语句之前调用 super(props);防止在构造函数中引入副作用或者订阅;防止将 props 的值赋值给 state(why?)。componentDidMount()调用工夫:React 组件挂载后(插入DOM 树中)立刻调用。 ...

January 25, 2021 · 5 min · jiezi

关于react.js:react简介

react生命周期 1.shouldComponentUpdate 的作用?shouldComponentUpdate 容许咱们手动地判断是否要进行组件更新,依据组件的利用场景设置函数的正当返回值可能帮咱们防止不必要的更新 2.React 中 keys 的作用是什么?Keys是 React 是for循环外面先比拟key值如果雷同,而后去比拟外面的内容,如果雷同就不必更新dom,只用更新最新数据变动,如果没有key值,如果key一样,若组件属性有所变动,则react只更新组件对应的属性;没有变动则不更新,如果key不一样,则react先销毁该组件,而后从新创立该组件 3.何为受控组件(controlled component)?比方<input/>, <select> 和 <textarea>如 onChange 会更新 state,从新渲染组件,而非受控组件是比方失去焦点或者提交按钮,须要的时候再去取就是非受控组件 4.setState 为什么是异步的保障外部的一致性 (因为props是要等到父组件渲染过后能力拿到,也就是不能同步更新,state出于统一性设成异步更新)性能优化 (举例说你正在一个聊天窗口输出,如果来了一条新音讯又要render,那就会阻塞你的以后操作,导致提早什么的)反对state在幕后渲染(异步能够使state在幕后更新,而不影响你以后旧的页面的交互,晋升用户体验)5.react性能优化计划重写shouldComponentUpdate来防止不必要的 dom 操作应用 production 版本的react.js应用key来帮忙React辨认列表中所有子组件的最小变动6.类组件和函数组件之间有什么区别?函数组件和类组件当然是有区别的,而且函数组件的性能比类组件的性能要高,因为类组件应用的时候要实例化,而函数组件间接执行函数取返回后果即可。为了进步性能,尽量应用函数组件。区别函数组件类组件是否有this没有有是否有生命周期没有有是否有状态state没有 7.state 和 props有什么区别props 是一个从内部传进组件的参数,次要作为就是从父组件向子组件传递数据,它具备可读性和不变性,只能通过内部组件被动传入新的 props 来从新渲染子组件,否则子组件的 props 以及展示模式不会扭转。state 的次要作用是用于组件保留、管制以及批改本人的状态,它只能在 constructor 中初始化,它算是组件的公有属性,不可通过内部拜访和批改,只能通过组件外部的 this.setState 来批改,批改 state 属性会导致组件的从新渲染。8.如何创立refs?class MyComponent extends React.Component { constructor(props) { super(props); this.myRef = React.createRef(); } render() { return <div ref={this.myRef} />; }}ref={(input) => this.input = input}9.constructor中super与props参数一起应用的目标是什么?在调用办法之前,子类构造函数无奈应用 this 援用 super() 。 在ES6中,在子类的 constructor 中必须先调用 super 能力援用 this 。 ...

January 25, 2021 · 1 min · jiezi

关于react.js:Apache服务的主要目录和配置文件详解

这篇文章次要介绍了Apache服务的次要目录和配置文件详解,须要的敌人能够参考下 一、Apache次要配置文件正文 Apache的主配置文件:/etc/httpd/conf/httpd.conf 默认站点主目录:/var/www/html/ Apache服务器的配置信息全副存储在主配置文件/etc/httpd/conf/httpd.conf中,这个文件中的内容十分多,用wc命令统计一共有1009行,其中大部分是以#结尾的正文行。 ServerTokensOS 在呈现谬误页的时候是否显示服务器操作系统的名称,ServerTokensProd为不显示 ServerRoot"/etc/httpd" 用于指定Apache的运行目录,服务启动之后主动将目录扭转为当前目录,在前面应用到的所有相对路径都是想对这个目录下 Userdaemon#apache的用户,默认为daemonGroupdaemon#apache的用户,默认为daemonPidFilerun/httpd.pid 记录httpd守护过程的pid号码,这是零碎辨认一个过程的办法,零碎中httpd过程能够有多个,但这个PID对应的过程是其余的父过程 Timeout60 服务器与客户端断开的工夫 KeepAliveOff 是否继续连贯(因为每次连贯都得三次握手,如果是访问量不大,倡议关上此项,如果网站访问量比拟大敞开此项比拟好),批改为:KeepAliveOn示意容许程序性联机 MaxKeepAliveRequests100 示意一个连贯的最大申请数 KeepAliveTimeout15 断开连接前的工夫 <IfModuleprefork.c>StartServers8MinSpareServers5MaxSpareServers20ServerLimit256MaxClients256MaxRequestsPerChild4000</IfModule> 零碎默认的模块,示意为每个拜访启动一个过程(即当有多个连贯专用一个过程的时候,在同一时刻只能有一个取得服务)。 StartServer开始服务时启动8个过程,最小闲暇5个过程,最多闲暇20个过程。 MaxClient限度同一时刻客户端的最大连贯申请数量超过的要进入等待队列。 MaxRequestsPerChild每个过程生存期内容许服务的最大申请数量,0示意永不完结 <IfModuleworker.c>StartServers4MaxClients300MinSpareThreads25MaxSpareThreads75ThreadsPerChild25MaxRequestsPerChild0</IfModule> 为Apache配置线程拜访,即每对WEB服务拜访启动一个线程,这样对内存占用率比拟小。 ServerLimit服务器容许配置过程数的下限。 ThreadLimit每个子过程可能配置的线程下限 StartServers启动两个httpd过程,MaxClients同时最多能发动250个拜访,超过的要进入队列期待,其大小有ServerLimit和ThreadsPerChild的乘积决定 ThreadsPerChild每个子过程生存期间常驻执行线程数,子线程建设之后将不再减少 MaxRequestsPerChild每个过程启动的最大线程数,如达到限度数时过程将完结,如置为0则子线程永不完结 Listen80 监听的端口,如有多块网卡,默认监听所有网卡 LoadModuleauth_basic_modulemodules/mod_auth_basic.so ...... LoadModuleversion_modulemodules/mod_version.so 启动时加载的模块 Includeconf.d/*.conf 加载的配置文件 启动服务后转网站监控换的身份,在启动服务时通常以root身份,而后转换身份,这样减少系统安全

January 25, 2021 · 1 min · jiezi

关于react.js:Redux在React-Hook中的使用及其原理

Hello, 各位怯懦的小伙伴, 大家好, 我是你们的嘴强王者小五, 身体健康, 脑子没病. 自己有丰盛的脱发技巧, 能让你一跃成为资深大咖. 一看就会一写就废是自己的宗旨, 菜到抠脚是自己的特点, 低微中透着一丝丝坚强, 傻人有傻福是对我最大的刺激. 欢送来到小五的随笔系列之Redux在React Hook中的应用及其原理. 浅谈Redux上面将从what, why, how to 三个方面来说说Redux 第一问 what ❓ 什么是Redux将一个web利用拆分成视图层与数据层, Redux就是保留其数据的一个容器, 其本质就是保护一个存储数据的对象. State : 一个存放数据的容器 (一个对象)const initState = { count: 0,}Action : 一个 want to do 的过程 (打算要做一个什么样的操作) ActionType是对Action的形容, 也是连贯Action和Reducer的桥梁实质上是一个由ActionType和payload(数据)组成的对象export const increaseConstant = 'INCREASE' // ActionType{ type: increaseConstant, payload,} // ActionReducer : 一个 to do 的过程 (执行Action打算的操作)case increaseConstant: // 当 ActionType 为 'INCREASE' 时, 执行count++ return { ...state, count: payload + 1 }第二问 why ❓ 为什么要应用Redux当你不晓得是否须要应用Redux的时候, 那就是不须要应用. ...

January 25, 2021 · 4 min · jiezi

关于react.js:深入-React-的-setState-机制

前言本篇写的 setState(波及源码局部)是针对 React15 版本,即是没有 Fiber 染指的;为了不便看和写,所以抉择旧版本,Fiber 写起来有点难,先留着将会写。setState 在 React 15 的原理能了解,16 版本的也是大同小异。 尽管曾经用 React Hooks 很久了,React15 的this.setState()模式都很少用了,但仍然是站在回顾与总结的角度,对待 React 的变迁和倒退,所以最近开始从新回顾以前只知其一;不知其二的一些原理问题,缓缓积淀技术。 setState 经典问题setState(updater, [callback])React 通过 this.setState() 来更新 state,当应用 this.setState()的时候 ,React 会调用 render 办法来从新渲染 UI。 setState 的几种用法就不必我说了,来看看网上探讨 setState 比拟多的问题: 批量更新import React, { Component } from 'react'class App extends Component { state = { count: 1, } handleClick = () => { this.setState({ count: this.state.count + 1, }) console.log(this.state.count) // 1 this.setState({ count: this.state.count + 1, }) console.log(this.state.count) // 1 this.setState({ count: this.state.count + 1, }) console.log(this.state.count) // 1 } render() { return ( <> <button onClick={this.handleClick}>加1</button> <div>{this.state.count}</div> </> ) }}export default App点击按钮触发事件,打印的都是 1,页面显示 count 的值为 2。 ...

January 25, 2021 · 5 min · jiezi

关于react.js:React10React-Context技术2

前言承接上一篇对于React Context技术的文章。React Context技术在页面主题批改利用上提供了较好的办法,同时React还提供了ContextType技术,用于实现对Context技术进行简化书写。本篇文章对这两个概念进行解说,最初再解说Context默认值的应用办法。 在开始正式解说之前, 再次强调React Context的性能:实现组件之间的数据传递。 一、案例:更改页面的主题1、案例要求页面中有两个超级链接,用于管制页面中内容的主题色彩。两个超级链接别离是“浅色主题”和“深色主题”。为了拆穿主题的更改,在页面中还设置了一个div容器,深浅色主题对应该div容器不同的背景色彩。div容器中有文本和一个命令按钮,深浅色主题也对应着文本的不同色彩和按钮的不同款式。案例的最终效果图如下所示。 2、案例剖析首先,咱们要在所有组件以外预设好两个主题的参数。依据对效果图的察看,两个不同的主题次要对应的是背景色彩、文本色彩、按钮色彩三个组成部分。布局具体的主题参数如下所示。 在上述表中,为按钮色彩布局的是Bootstrap框架中的两种不同的按钮背景色彩类。如果不应用Bootstrap,也能够在CSS文件中独立书写这两个类,并为这两个类设置不同的外观。 依照上述表中的外观布局,定义一个themes的对象,蕴含两种主题款式,代码如下所示。 const themes={ light:{ className:'btn btn-primary', backgroundColor:'#ddd', color:'#000' }, dark:{ className:'btn btn-danger', backgroundColor:'#222', color:'#fff' }};3、案例组件划分其次,咱们来为这个案例进行组件划分。很显然,咱们能够将其划分为两个组件: 父组件<App />:实现扭转主题的超级链接和整个案例的布局。子组件<Content />:实现案例下方的<div>容器和其外部的文本与按钮。4、<App />组件的实现在书写组件<App />时,要先创立Context对象,并解构出生产组件和生产组件。 const {Provider,Consumer} = React.createContext();为了能将用户所选的主题传递给子组件,来让子组件扭转款式,咱们须要在父组件中创立一个state数据,命名为themeData。该数据的默认值为‘light’,示意默认为浅色主题。当用户单击深色主题超级链接时,扭转themeData数据的值为‘dark’。同时将这个themeData作为数据传递给子组件。 <App />组件的代码如下所示。 class App extends Component { constructor(props){ super(props); this.state={ themeData:'light' } } changeTheme(data){ this.setState({ themeData:data }) } render(){ return ( <Provider value={this.state.themeData}> <div className="theme"> <a href="#" onClick={()=>this.changeTheme('dark')}>深色主体</a> <a href="#" onClick={()=>this.changeTheme('light')}>浅色主题</a> </div> <Content></Content> </Provider> ) }}5、<Content />组件的实现该组件作为<App />组件的生产组件,要是用<Consumer>组件接管<App />组件传来的数据。即接管的数据为一个字符串:‘light’或‘dark’。而后再从示意主题的themes对象中,寻找对应字符串成员的各种款式取值。 ...

January 18, 2021 · 1 min · jiezi

关于react.js:TypeScript与React中如何使用ref

父组件在父组件中,编写如下: 类中定义child,用于寄存子组件的作用域 public child: any;Copy to clipboardErrorCopied绑定子组件作用域 public onRef(ref:any){ this.child = ref}Copy to clipboardErrorCopied子组件上绑定ref <ChildPage onRef={(el)=>this.onRef(el)} />Copy to clipboardErrorCopiedonRef 绑定this(第3步,不应用箭头函数的状况)this.onRef = this.onRef.bind(this)Copy to clipboardErrorCopied子组件在子组件中,编写如下: constructor中onRef绑定this this.props.onRef(this)Copy to clipboardErrorCopied实现以上4步骤,父组件中能够轻易调用子组件中state的值以及办法。 export class ParentCom extends React.Component<{}, {}> { constructor(props:{}){ super(props); this.onRef = this.onRef.bind(this); } public child: any; onRef(ref:any){ this.child = ref; } getChildFun(){ this.child.testFun(); } render(){ return ( <div> <span>父组件</span> <ChildCom onRef={this.onRef}></ChildCom> </div> ) }}interface childProps{ onRef? : any}export class ChildCom extends React.Component<childProps, {}> { constructor(props:{}){ super(props); this.props.onRef(this); } testFun(){ console.log(123) } render(){ return ( <div> <span>子组件</span> </div> ) }}

January 6, 2021 · 1 min · jiezi

关于react.js:展望新的2021

新的一年的瞻望新的一年先立一个flag,冀望年尾都实现,不要啪啪打脸。。。 1.读10+以上的书(包含前端技术及以外的书);2.深挖react的技术栈;3.vue3.0把握并深挖相应的技术栈;4.健身锤炼,减到120斤;5.脱单!!!

January 6, 2021 · 1 min · jiezi

关于react.js:dvaloading使用总结

在开发异步加载的性能时,为进步用户体验个别会显示加载提醒,最近在应用umi做我的项目时接触到dva-loading,对全局和部分组件的异步加载管制还是十分不便的。 在umi中应用装置和配置装置 npm install dva-loading -S后,进入src/app.js对 dva 进行运行时配置: import createLoading from "dva-loading"export const dva = { plugins: [createLoading()]}models在models文件夹下新建count.js文件,输出上面内容进行测试: const delay = (ms)=>new Promise(r=>setTimeout(r,ms))export default { namespace:"count", state:{ count:1, }, effects:{ *add(action,{put,call}){ yield call(delay,1000); yield put({type:"change",payload:Math.random()}) } }, reducers:{ change(state,{payload}){ return {count:state.count+payload} } }}组件中应用新建Count.js组件进行测试: import React from "react"import { connect } from "dva"function Count({ dispatch, count, loading }) { const isLoading = loading.models.count; // 独自对 effects 管制 // const isLoading = loading.effects["count/add"] // 对多个 effects 管制 // const isLoading = loading.effects["count/add"] || loading.effects["count/minus"] || false; return ( <div> {isLoading ? <p>加载中...</p> : <p>{count}</p>} <button onClick={() => dispatch({ type: "count/add" })}>+</button> </div> )}export default connect((state) => ({ ...state.count, loading: state.loading }))(Count)dav-loading往全局的state中注入了loading,咱们能够拿到loading对象判断组件的model或者effect状态。 ...

January 5, 2021 · 3 min · jiezi

关于react.js:React-瀑布流实践

需要在业务中须要在web页面依据搜寻的后果渲染出瀑布流款式的后果页面,我实现成果如下(感觉不太称心,他并不是通过计算最小高度而后主动填补,而是依照几列几行来一个个填补,前面有更深刻的研究会更新,这是一种赶工实现的形式): 实现办法尝试了间接应用flex布局,存在较大的缺点,尽管看似实现了,但对于特地的图片显示还是很奇怪,不够贴合,起初查问了几种插件,不是说他们都不好,试下的成果应该是相似的,都是通过计算图形的宽高来进行布局的,不过有些对于数据中蕴含的信息要求比拟高,让后盾在我的数据外面塞图形宽高曾经是我这个小前端的极限了!!最初找到了一个 react-grid-layout 插件,感激大佬小翼在答复中提供的几种插件。 代码import React, { Component } from "react";import styles from "./styles.module.less";// 引入lodashimport _ from "lodash";// 引入组件import RGL, { WidthProvider } from "react-grid-layout";// 包装组件const ReactGridLayout = WidthProvider(RGL);// 定义案例数组数据const items = [ { url: "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=384124318,1246746555&fm=26&gp=0.jpg", width: 540, height: 300, }, { url: "https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2435568812,3959731342&fm=11&gp=0.jpg", width: 499, height: 320, }, { url: "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3341500380,460051199&fm=11&gp=0.jpg", width: 604, height: 300, }, { url: "https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2435568812,3959731342&fm=11&gp=0.jpg", width: 499, height: 320, }, { url: "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3341500380,460051199&fm=11&gp=0.jpg", width: 604, height: 300, }, { url: "https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3426709235,3578542279&fm=26&gp=0.jpg", width: 500, height: 210, }, { url: "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1322120441,3602413475&fm=26&gp=0.jpg", width: 400, height: 183, }, { url: "https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3426709235,3578542279&fm=26&gp=0.jpg", width: 500, height: 210, }, { url: "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3341500380,460051199&fm=11&gp=0.jpg", width: 604, height: 300, }, { url: "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1322120441,3602413475&fm=26&gp=0.jpg", width: 400, height: 183, }, { url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fi2.hdslb.com%2Fbfs%2Farchive%2F3c7a5b24b38ac3216182e0bf026622801d10c3fa.jpg&refer=http%3A%2F%2Fi2.hdslb.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1612319581&t=9486804e3256336fd0d2c2865d929d6c", width: 1728, height: 1080, }, { url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic.51yuansu.com%2Fpic3%2Fcover%2F02%2F85%2F29%2F5a61c19d6a659_610.jpg&refer=http%3A%2F%2Fpic.51yuansu.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1612319668&t=aaa48c2a20b18f021f8058d7bd882dfb", width: 610, height: 1295, },];// 定义一个父组件,次要是为了进行容器大小的变动监听,而后动静设置高度export default class About extends Component { constructor(props) { super(props); // 行高初始化,这是我本人的行高,依据以后容器大小计算出来的 this.state = { rowHeight: 110 }; } componentDidMount() { // 初始化size监听函数 this.screenChange(); } // 卸载size监听函数 componentWillUnmount() { window.removeEventListener("resize", this.resize); } // size监听函数 screenChange = () => { window.addEventListener("resize", this.resize); }; // 区域宽高变动时触发行高的变动 resize = () => { const box = document.getElementById("watar-fall"); let width = box.clientWidth; let rowHeight = (width - 100) / 12; this.setState({ rowHeight }); console.log(width); }; render() { // 将行高作为props传入子组件 const { rowHeight } = this.state; return ( <div className={styles.bside_main_container} id="watar-fall"> <WaterFall rowHeight={rowHeight} items={items}></WaterFall> </div> ); }}// 定义的瀑布流子组件,真是利用能够独自封装在内部class WaterFall extends Component { // 默认的props static defaultProps = { className: "layout", isDraggable: false, isResizable: false, cols: 12, rowHeight: 110, }; constructor(props) { super(props); // 初始化定义layout 和渲染的数据 this.state = { layout: this.generateLayout([]), data: [] }; } // 加载的时候更新layout和data componentDidMount() { this.setState({ data: [...this.props.items], layout: this.generateLayout(this.props.items), }); } // 生成每一个瀑布流内item 的函数 generateDOM = () => { const { data } = this.state; return _.map(_.range(data.length), function (i) { return ( // 这里的key值和layout外面的要对应,所以不要用其余值代替 <div key={i} className={styles.box}> {/*在这里能够自定义你要的显示款式 */} <img src={data[i].url} alt="ff" style={{ width: "100%" }}></img> </div> ); }); }; // 生成layout的数组函数 generateLayout = (items) => { // 循环数据返回相应的layout return _.map(new Array(items.length), function (item, i) { // 在这里设置每一个图片的高度。我是通过图片的宽而后依据所占行的比例,计算出来的等比高度 let y = (3 / items[i].width) * items[i].height; return { x: (i * 3) % 12, // 每个图片的起始x点 ,因为是4列,所以在12列外面是3列一个图片 y: Math.floor(i / 4) * y, // 距离四个换行 w: 3, // 图片占的列数 h: y, // 计算所得的图片高度 i: i.toString(), // layout的key值 }; }); }; render() { return ( <div className={styles.container}> {/* 传入参数并生成瀑布流 */} <ReactGridLayout layout={this.state.layout} {...this.props}> {this.generateDOM()} </ReactGridLayout> </div> ); }}总结这次根本的实现是这样,这个组件原本更弱小的中央应该是在可拖拽的方面,我这算是千里之堤;溃于蚁穴了,前面如果有工夫再钻研一下其余瀑布流或者本人写一个js组件吧。(如果我写的有什么问题,欢送斧正!) ...

January 5, 2021 · 2 min · jiezi

关于react.js:React-整体感知

当咱们由浅入深地认知一样新事物的时候,往往须要遵循 Why > What > How 这样一个认知过程。它们是相辅相成、缺一不可的。而理解了具体的 What 和 How 之后,往往可能更加具象地答复实践层面的 Why,因而,在进入 Why 的摸索之前,咱们先整体感知一下 What 和 How 两个过程。 What关上 React 官网,第一眼便能看到官网给出的答复。 React 是用于构建用户界面的 JavaScript 库。不晓得你有没有想过,构建用户界面的形式有千百种,为什么 React 会突出?同样,咱们能够从 React 哲学里失去回应。 咱们认为, React 是用 JavaScript 构建疾速响应的大型 Web 应用程序的首选形式。它在 Facebook 和 Instagram 上体现优良。可见,要害是实现了 疾速响应 ,那么制约 疾速响应 的因素有哪些呢?React 是如何解决的呢? How让咱们带着下面的两个问题,在遵循实在的React代码架构的前提下,实现一个蕴含工夫切片、fiber、Hooks的繁难 React,并舍弃局部优化代码和非必要的性能,将其命名为 HuaMu。 留神:为了和源码有点辨别,函数名首字母大写,源码是小写。CreateElement 函数在开始之前,咱们先简略的理解一下JSX,如果你感兴趣,能够关注下一篇《JSX背地的故事》。 JSX会被工具链Babel编译为React.createElement(),接着React.createElement()返回一个叫作React.Element的JS对象。 这么说有些形象,通过上面demo看下转换前后的代码: // JSX 转换前const el = <h1 title="el_title">HuaMu<h1>;// 转换后的 JS 对象const el = { type:"h1", props:{ title:"el_title", children:"HuaMu", }}可见,元素是具备 type 和 props 属性的对象,而 CreateElement 函数的次要工作就是创立该对象。 ...

January 4, 2021 · 6 min · jiezi

关于react.js:React7React非受控组件的使用

前言上一篇文章咱们零碎解说了React表单受控组件的应用,对于文本框、列表、菜单来说,采纳value-onChange组合来实现。对于单选框、复选框来说,采纳checked-onChange组合来实现。除了受控组件,React还提供了非受控组件,本篇文章来为大家解说非受控组件的应用办法。 非受控组件是指表单元素的操作不受组件中state区数据的管制,也不须要将表单元素的状态与任何数据双向绑定,这种操作形式下的表单元素被称为“非受控组件”。非受控组件与受控组件不同,要联合标记对独特应用。 一、非受控文本框的应用非受控文本框在应用时要遵循下列应用标准: 非受控文本框应用defaultValue属性来设置初始数据,该属性在react中是只读属性,不能绑定state区数据,也不能从新赋值。非受控文本框须要设置ref属性,以保障在表单的提交事件中通过this.refs来获取文本框中用户输出的内容。在应用非受控组件时,须要为标记设置onSubmit事件,即表单的提交事件。在表单中具备提交性能的按钮被单击时,该事件会主动触发。例1:在页面中有一个用于输出用户昵称的文本框,在按钮单击时将用户输出的昵称在控制台中显示。const {Component,Fragment} = React;class App extends Component{frmSubmit(event){ event.preventDefault() let nick=this.refs.userNick.value; console.log(nick) } render(){ return ( <Fragment> <form onSubmit={(event)=>this.frmSubmit(event)}> <label htmlFor="nick">您的昵称</label> <p><input ref="userNick" type="text" id="nick" defaultValue="" /></p> <button>提交</button> </form> </Fragment> ) }} 从上述代码中能够看出,非受控组件在应用时是不须要state区的,defaultValue之所以设置为空字符串,因为该属性只用来设置文本框的默认取值,如果没有默认取值,该属性也能够省略不写。 二、非受控select菜单的应用非受控select菜单和非受控文本框的应用办法是一样的。 例2:页面中有一个用于抉择所学业余的select下拉菜单,单击按钮在控制台中显示用户抉择的业余项。const {Component,Fragment} = React;class App extends Component{ frmSubmit(event){ event.preventDefault() let spec=this.refs.userSpec.value; console.log(spec); } render(){ return ( <Fragment> <form onSubmit={(event)=>this.frmSubmit(event)}> <div> <label htmlFor="spec">所学业余:</label> <select ref="userSpec"> <option value="计算机网络">计算机网络</option> <option value="计算机利用">计算机利用</option> <option value="计算机科学与技术">计算机科学与技术</option> <option value="计算机信息治理">计算机信息治理</option> <option value="计算机软件工程">计算机软件工程</option> </select> </div> <button>提交</button> </form> </Fragment> ) }} 三、非受控select列表的应用非受控select列表因为具备多选性能,因而在解决时更靠近原生JavaScript中DOM操作的形式。 ...

January 4, 2021 · 1 min · jiezi

关于react.js:React5React兄弟组件之间的通信

前言上一篇文章咱们通过一个ToDoList案例,零碎的解说了React父子组件之间的通信。本篇文章咱们仍然通过一个实用的案例来为大家解说React兄弟组件之间的通信。 一、兄弟组件之间的通信原理React我的项目中的两个兄弟组件若要传递数据,则首先须要先将数据从一个兄弟组件传递给他们的公共父组件,而后再由这个公共父组件将数据传递给另一个兄弟组件。数据传递的原理如下图所示。咱们通过一个案例来阐明兄弟组件之间的通信形式。该案例是一个色彩调色板,页面中有三个滑竿,别离能够调整红色、绿色、蓝色的取值范畴(0-255),在调整任意滑竿的过程中,会主动显示最终生成的颜色代码,并将具体的色彩展现在一个div容器中。案例效果图如下图所示。 该案例为了实现兄弟组件之间的数据传递,咱们将其划分为三个组件。 父组件:Color,用于调用两个子组件,并且显示最终的颜色代码。子组件1:ColorBoard,用于显示色彩拾取器中展现具体色彩的div容器。子组件2:ColorSelector,用于实现调整色彩的三个滑竿。 本案例中,三个滑竿的取值决定了最终的颜色代码和色彩展现。所以初始化的数据位于组件ColorSelector中,当滑竿发生变化时,三个滑竿的取值都要传递给父组件,父组件将其转换为颜色代码,再传递给子组件ColorBoard,子组件将其作用在用于展现色彩的div的背景色彩属性上。组件之间数据的传递方向如下图所示。 二、三个组件的根本构造咱们将组件划分好之后,先依照效果图将各个组件的元素地位书写好。 1、子组件ColorSelector的根本构造class ColorSelector extends Component{ constructor(props){ super(props); this.state={ colors:[255,255,255] } } render(){ return ( <Fragment> { this.state.colors.map((item,index)=>{ return <input type="range" key={index} min={0} max={255} /> }) } </Fragment> ) }} 为了可能获取三个滑竿的最终数值,咱们在state区设置了一个名为colors的数据,该数据是一个数组,共有三个数组元素,别离用来示意三个滑竿的最终数值。 滑竿也属于表单元数,和上一篇文章中应用文本框的办法是一样的。为滑竿增加value属性设置默认值,绑定onChange事件获取用户交互数据,在onChange事件中应用event.target.value失去最终的后果。所以上述代码中滑竿的局部最终变为下列格局。 return <input type="range" key={index} min={0} max={255} value={item} onChange={()=>this.colorChange(event,index)} /> 2、子组件ColorBoard的根本构造class ColorBoard extends Component{ render(){ return ( <Fragment> <div className="board"></div> </Fragment> ) }} ColorBoard组件只具备一个div容器,最终会接管父组件Color传递过去的颜色代码并通过style属性扭转背景色彩。 3、父组件Color的根本构造class Color extends Component{ constructor(props) { super(props); this.state={ color:'#FFFFFF' } } render(){ return ( <Fragment> <ColorBoard /> <div>颜色代码:{this.state.color}</div> <ColorSelector /> </Fragment> ) }} 父组件为了承受子组件ColorSelector传递过去的数组并最终转换为颜色代码,在其state区设置了一个名为color的数据。 ...

January 2, 2021 · 2 min · jiezi

关于react.js:React6React受控组件的使用

前言在一个理论的我的项目中,表单是必不可少的DOM元素。我的项目中呈现的表单元素,React要如何获取用户在表单元素中书写或抉择的内容呢?本篇文章就为大家解说React中受控组件的应用办法。受控组件:Controlled Component,组件的数据受到state组件状态的管制,咱们将这类组件称为“受控组件”。受控组件在应用时要实现组件数据和state组件状态的双向绑定。 一、文本类表单元素的受控控应用办法文本类表单元素包含文本域、明码域、多行文本域三种表单元素。它们应用value属性来绑定表单元素的默认值,同时应用onChange事件编写当文本内容发生变化时所执行的代码。咱们将这种用法称为“value-onChange”组合。 例1:在页面中有一个用于输出昵称的表单元素和一个按钮。用户在文本框中输出本人的昵称,单击按钮后获取用户输出的昵称内容,并在控制台中显示。class App extends React.Component { constructor(props){ super(props); this.state={ nick:"" } } render(){ return ( <React.Fragment> <label htmlFor="nick">昵称</label> <input type="text" id="nick" value={this.state.nick} onChange={(event)=>{this.nickChange(event)}} /> <div><button onClick={()=>this.getNick()}>获取昵称</button></div> </React.Fragment> ) }} 从上述代码中能够看出,文本框利用value属性绑定了state区的nick数据作为文本框的默认值,即空字符串。同时又为文本框绑定了onChange事件。该事件只须要将文本框中用户输出的内容赋值给state区的nick数据即可。文本框中用户输出的内容能够应用onChange事件函数中的event.tarvar.value获取。 文本框的onChange事件代码如下所示。 onChange(event){ this.setState({ nick:event.target.value })} 按钮的单击事件代码如下所示。 getNick(){ console.log(this.state.nick);} 从例1中能够看出,文本框中的value属性只能为文本框绑定一个初始值,当文本框中的文本内容发生变化时,还须要借助onChange事件来将文本框的值赋给value属性当初绑定的state数据。 例2:在页面中有一个用于输出留言的多行文本域和一个按钮。用户在多行文本框中输出留言文本,单击按钮后获取用户输出的留言内容,并在控制台中显示。同时随着用户输出文本的增多,在页面中显示曾经输出了多少个字符,同时限度最多输出20个字符。效果图如下所示。 class App extends React.Component { constructor(props){ super(props); this.state={ message:"", inputed:0, total:20 } } render(){ return ( <React.Fragment> <label htmlFor="message">留言:(已输出{this.state.inputed}/{this.state.total})</label> <textarea id="message" value={this.state.message} onChange={(event)=>{this.messageChange(event)}></textarea> <div><button onClick={()=>this.submitMessage()}>提交留言</button></div> </React.Fragment> ) }} 多行文本域的解决形式和文本域的解决形式雷同,都是采纳value-onChange组合来实现的。当用户在多行文本域中输出内容时,将触发onChange事件,该事件代码如下所示。 ...

January 2, 2021 · 2 min · jiezi

关于react.js:2021十大科技趋势来了阿里巴巴达摩院全新发布

阿里巴巴达摩院公布2021十大科技趋势,这是达摩院成立三年以来第三次公布年度科技趋势。 2020年是不平庸的一年,经验疫情的洗礼,许多行业重启向上而生的螺旋,但疫情并未阻挡科技后退的脚步,量子计算、根底资料、生物医疗等畛域的一系列重大科技冲破络绎不绝。 后疫情时代,根底技术及科技产业将如何倒退,达摩院为科技行业提供了全新预测。 趋势一 以氮化镓、碳化硅为代表的第三代半导体迎来利用大暴发 以氮化镓(GaN)和碳化硅(SiC)为代表的第三代半导体,具备耐高温、耐低压、高频率、大功率、抗辐射等优异个性,但受工艺、老本等因素限度,多年来仅限于小范畴利用。 近年来,随着资料成长、器件制备等技术的一直冲破,第三代半导体的性价比劣势逐步浮现,并正在关上利用市场:SiC元件已用作汽车逆变器,GaN疾速充电器也大量上市。 将来五年,基于第三代半导体资料的电子器件将广泛应用于5G基站、新能源汽车、特高压、数据中心等场景。 趋势二 后“量子霸权”时代,量子纠错和实用劣势成外围命题 2020年为后“量子霸权”元年,世界对量子计算的投入继续上涨,技术和生态蓬勃发展,多个平台异彩缤纷。 这一潮流将在2021年持续推高社会的关注和期待,量子计算的钻研须要证实本身的实用价值;业界须要聚焦“后霸权”时代的使命:协同翻新,解决泛滥的迷信和工程难题,为早日达到量子纠错和实用劣势两座里程碑铺路奠基。 趋势三 碳基技术冲破减速柔性电子倒退 柔性电子是指经扭曲、折叠、拉伸等形态变动后仍放弃原有性能的电子设备,可用作可穿戴设施、电子皮肤、柔性显示屏等。 柔性电子倒退的次要瓶颈在于资料——目前的柔性资料,或者“柔性”有余容易生效,或者电性能远不如“硬质”硅基电子。 近年来,碳基资料的技术冲破为柔性电子提供了更好的资料抉择:碳纳米管这一碳基柔性资料的品质已可满足大规模集成电路的制备要求,且在此资料上制备的电路性能超过同尺寸下的硅基电路;而另一碳基柔性资料石墨烯的大面积制备也已实现。 趋势四 AI晋升药物及疫苗研发效率 AI已广泛应用于医疗影像、病历治理等辅助诊断场景,但AI在疫苗研发及药物临床钻研的利用仍旧处于摸索阶段。 随着新型AI算法的迭代及算力的冲破,AI将无效解决疫苗/药物研发周期长、老本低等难题,例如晋升化合物筛选、建设疾病模型、发现新靶点、先导化合物发现及先导药物优化等环节的效率。 AI与疫苗、药物临床钻研的联合能够缩小重复劳动与工夫耗费,晋升研发效率,极大地推动医疗服务和药物的普惠化。 趋势五 脑机接口帮忙人类超过生物学极限 脑机接口是新一代人机交互和人机混合智能的要害核心技术。脑机接口对神经工程的倒退起到了重要撑持与推动作用,帮忙人类从更高维度空间进一步解析人类大脑的工作原理。 脑机接口这一新技术畛域,探索性地将大脑与外部设备进行通信,并借由脑力意念管制机器。例如在管制机械臂等方面帮忙晋升利用精度,将为神智清醒、思维健全,但口不能言、手不能动的患者提供精准痊愈服务。 趋势六 数据处理实现“自治与自我进化” 随着云计算的倒退、数据规模继续指数级增长,传统数据处理面临存储老本高、集群治理简单、计算工作多样性等微小挑战;面对海量暴增的数据规模以及简单多元的解决场景,人工治理和零碎调优顾此失彼。 因而,通过智能化办法实现数据管理系统的主动优化,成为将来数据处理倒退的必然选择。 人工智能和机器学习伎俩逐步被广泛应用于智能化的冷热数据分层、异样检测、智能建模、资源调动、参数调优、压测生成、索引举荐等畛域,无效升高数据计算、解决、存储、运维的治理老本,实现数据管理系统的“自治与自我进化”。 趋势七 云原生重塑IT技术体系 在传统IT开发环境里,产品开发上线周期长、研发效力不高,云原生架构充分利用了云计算的分布式、可扩大和灵便的个性,更高效地利用和治理异构硬件和环境下的各类云计算资源。通过方法论工具集、最佳实际和产品技术,开发人员可专一于利用开发过程自身。 将来,芯片、开发平台、应用软件乃至计算机等将诞生于云上,可将网络、服务器、操作系统等基础架构层高度抽象化,升高计算成本、晋升迭代效率,大幅升高云计算应用门槛、拓展技术利用边界。 趋势八 农业迈入数据智能时代 传统农业产业倒退存在土地资源利用率低和从生产到批发链路脱节等瓶颈问题。以物联网、人工智能、云计算等为代表的数字技术正在与农业产业深度交融,买通农业产业的全链路流程。 联合新一代传感器技术,农田高空数据信息得以实时获取和感知,并依附大数据分析与人工智能技术疾速解决海量畛域农业数据,实现农作物监测、精细化育种和环境资源按需分配。 同时,通过5G、物联网、区块链等技术的利用,确保农产品物流运输中的可控和可追溯,保障农产品整体供应链流程的安全可靠。农业将辞别“靠天”吃饭,进入智慧农业时代。 趋势九 工业互联网从单点智能走向全局智能 受施行老本和复杂度较高、供应侧数据难以买通、整体生态不够欠缺等因素限度,目前的工业智能仍以解决碎片化需要为主。 疫情中数字经济所展示进去的韧性,让企业更加器重工业智能的价值,加之数字技术的提高遍及、新基建的投资拉动,这些因素将独特推动工业智能从单点智能疾速跃迁到全局智能。 特地是汽车、生产电子、品牌服饰、钢铁、水泥、化工等具备良好信息化根底的制造业,贯通供应链、生产、资产、物流、销售等各环节在内的企业生产决策闭环的全局智能化利用,将大规模涌现。 趋势十 智慧经营核心成为将来城市标配 在过来十年工夫里,智慧城市借助数字化伎俩切实晋升了城市治理程度。但在新冠疫情防控中,智慧城市裸露出新问题,特地是因为“重建设轻经营”所导致的业务利用有余。 在此背景下,城市将来须要通过经营核心盘活数据资源,推动治理与服务的全局化、精细化和实时化。 而AIoT技术的日渐成熟和遍及、空间计算技术的提高,将进一步晋升经营核心的智慧化程度,在数字孪生根底上把城市作为对立零碎并提供整体智慧治理能力,进而成为将来城市的数字基础设施。 原文链接本文为阿里云原创内容,未经容许不得转载

December 30, 2020 · 1 min · jiezi

关于react.js:Typescript高性能

有些简略的Typescript配置,能够让你取得更快的编译和编辑体验,这些办法越早把握越好。上面列举了除了最佳实际以外,还有一些用于考察迟缓的编译/编辑体验的罕用技术,以及一些作为最初伎俩来帮忙TypeScript团队考察问题的罕用办法。 编写易编译代码优先应用接口而不是穿插类型很多时候,简略对象类型的类型别名与接口的作用十分类似 然而,只有你须要定义两个及以上的类型,你就能够选用接口来扩大这些类型,或者在类型别名中对它们相交,这时差别就变得显著了。 因为接口定义的是繁多立体对象类型,能够检测属性是否抵触,解决这些抵触是十分必要的。另一方面,穿插类型只是递归的合并属性,有些状况下会产生never。接口则体现的一贯很好,而穿插类型定义的类型别名不能显示在其余的穿插类型上。接口之间的类型关系也会被缓存,而不是整个穿插类型。最初值得注意的区别是,如果是穿插类型,会在查看“无效” /“展平”类型之前查看所有属性。 因而,倡议在创立穿插类型时应用带有接口/扩大的扩大类型。 应用类型正文增加类型正文,尤其是返回类型,能够节俭编译器的大量工作。这是因为命名类型比匿名类型更简洁(编译器更喜爱),这缩小了大量的读写申明文件的工夫。尽管类型推导是十分不便的,没有必要到处这么做。然而,如果您晓得了代码的慢速局部,可能会很有用。 优先应用根底类型而不是联结类型联结类型十分好用--它能够让你表白一种类型的可能值范畴。 然而他们也带来了肯定开销。每次将参数传递给 printSchedule 时,须要比拟联结类型里的每个元素。对于一个由两个元素组成的联结类型来说,这是微不足道的。然而,如果你的联结类型有很多元素,这将引起编译速度的问题。例如,从联结类型中淘汰多余的局部,元素须要成对的去比拟,工作量是呈二次递增的。当大量联结类型穿插一起时产生这种查看,会在每个联结类型上相交导致大量的类型,须要缩小这种状况产生。防止这种状况的一种办法是应用子类型,而不是联结类型。 一个更事实的例子是,定义每种内置DOM元素的类型时。这种状况下,更优雅的形式是创立一个蕴含所有元素的 HtmlElement 根底类型,其中包含 DivElement 、 ImgElement 等。应用继承而不是创立一个无穷多的联结类型 DivElement | /\*...\*/ | ImgElement | /\*...\*/ 。 应用我的项目援用应用TypeScript构建内容较多的代码时,将代码库组织成几个独立的我的项目会很有用。每个我的项目都有本人的 tsconfig.json ,可能它会对其余我的项目有依赖性。这有益于防止在一次编译中导入太多文件,也使某些代码库布局策略更容易地放在一起。 有一些十分根本的办法将一个代码库分解成多个我的项目。举个例子,一个程序代码,一部分用作客户端,一部分用作服务端,另一部分被其它两个共享 测试也能够合成到本人的我的项目中 一个常见的问题是 "一个我的项目应该有多大?"。这很像问 "一个函数应该有多大?"或 "一个类应该有多大?",在很大水平上,这归纳于教训。人们相熟的一种宰割JS/TS代码的办法是应用文件夹。作为一种启发式的办法,如果它们关联性足够大,能够放在同一个文件夹中,那么它们就属于同一个我的项目。除此之外,要避免出现极大或极小规模的我的项目。如果一个我的项目比其余所有我的项目加起来都要大,那就是一个正告信号。同样,最好防止有几十个单文件我的项目,因为也会减少开销。 你能够在这里浏览更多对于我的项目参考资料 配置tsconfig.json或jsconfig.jsonTypeScript和JavaScript用户能够用tsconfig.json文件任意配置编译形式。JavaScript用户也能够应用jsconfig.json文件配置本人的编辑体验。 指定文件你应该始终确保你的配置文件没有蕴含太多文件 在 tsconfig.json 中,有两种形式能够指定我的项目中的文件 files列表include、exclude列表两者的次要区别是,files冀望失去一个源文件的文件门路列表,而include/exclude应用通配符模式对文件进行匹配 尽管指定文件能够让TypeScript间接疾速地加载文件,但如果你的我的项目中有很多文件,而不只是几个顶层的入口,那就会很麻烦。此外,很容易遗记增加新文件到tsconfig.json中,这意味着你可能最终会失去奇怪的编辑器行为,这些新文件被谬误地剖析,这些都很辣手。 include/exclude有助于防止指定这些文件,但代价是:必须通过include蕴含的目录来发现文件。当运行大量的文件夹时,这可能会减慢编译速度。此外,有时编译会蕴含很多不必要的.d.ts文件和测试文件,这会减少编译工夫和内存开销。最初,尽管exclude有一些正当的默认值,但某些配置比方mono-repos,意味着像node_modules这样的 "重 "文件夹依然能够最终被蕴含。 对于最佳做法,咱们倡议如下: 在您的我的项目中只指定输出文件夹(即您想将其源代码蕴含在编译/剖析中的文件夹)不要把其余我的项目的源文件混在同一个文件夹里如果把测试和其余源文件放在同一个文件夹里,请给它们取一个不同的名字,这样就能够很容易地把它们排除在外防止在源目录中呈现大的构建工件和依赖文件夹,如node_modules留神:如果没有排除列表,默认状况下node_modules是被排除的;一旦增加了node_modules,就必须明确地将node_modules增加到列表中。 上面是一个正当的tsconfig.json,用来演示这个操作 管制蕴含的@types默认状况下,TypeScript会主动蕴含每一个在node_modules文件夹中找到的@types包,不论你是否导入它。这是为了在应用Node.js、Jasmine、Mocha、Chai等工具_包时,使某些货色 "可能工作",因为这些工具_包没有被导入--它们只是被加载到全局环境中 有时这种逻辑在编译和编辑场景下都会拖慢程序的构建工夫,甚至会造成多个全局包的申明抵触的问题,造成相似于如下问题 在不须要全局包的状况下,修复办法很简略,只有在 tsconfig.json/jsconfig.json 中为 "type "选项指定一个空字段即可。 ...

December 29, 2020 · 1 min · jiezi

关于react.js:Email账号激活密码找回

咱们在很多时候(比方重置明码),都须要用户的Email。但在应用之前,须要保障用户输出的Email是: 真实有效,且属于以后用户的惯常的方法就是对其进行验证/激活。 策略 如图所示: 用户:输出他的Email地址,提交给服务器服务器:为该Email生成一个验证码code(为了平安期间,还能够有一个无限截止工夫),将email和code一起保留到数据库服务器:将验证码code发送到该Email中。为了不便用户操作,通常是发送一个链接,链接中蕴含该code和Email的Id用户:从Email邮箱中取得code(或者间接点击发送过去的链接),到服务器激活服务器:将用户输出的code和数据库中的存储的值进行比对,如果无误的话,激活该email(email.IsValid=true)整个流程的要害就在于:用户只能通过他留下的email获取激活code。 实现 发送EmailEmail并不能在用户之间间接传递,而是依赖于邮件的: 发送服务器(如下图:smtp.163.com)接管服务器(如下图:pop.qq.com) 发送方(sender)将email推送给邮件发送服务器。这一过程能够由用户登录邮箱网站实现,或应用其余邮箱软件(如outlook)推送163.com按邮件收件人地址将email推送到qq.com服务器收件方(receiver)从服务器拉取本人的email上述3个过程,1和2都是推送,应用SMTP(Simple Mail Transfer Protocol)协定;3是拉取,应用的是POP3协定。 咱们开发只关注第1个阶段。.NET为咱们提供了现成的类库: 首先,引入命名空间: using System.Net.Mail; //留神不要援用成System.Web.Mail而后,用一个MailMessage对象配置Email自身的相干信息: MailMessage mail = new MailMessage();mail.From = new MailAddress(ConfigurationManager.AppSettings["EmailAddress"]);mail.To.Add(address);mail.Subject = "激活Email";mail.IsBodyHtml = true; //最终出现款式由收件服务器决定mail.Body = $"感激你的注册……";接下来,配置SMTP服务器(本人邮箱所在)不能应用SSL形式发送 邮箱地址:feige_20200214@163.com 明码:yuanzhan17bang(登录) / yz17bang(客户端受权) (演示:略) 中的难点: 按职责:url格局(应用的http协定、域名、门路、url参数名等)均在UI层生成 string validationUrlFormat = $"{Request.Scheme}://{Request.Host}/Email/Validate?{_code}={{0}}&{_id}={{1}}";Email验证码应在BLL层生成 public void MakeValidationCode() { ValidationCode = new Random().Next().ToString(); }Email的Id须要在Email被Repository存储之后能力生成 public void Save(Email email) { Emails.Add(email); SaveChanges(); }那么,Email的发送应该是哪一个层的职责?如何保障验证码只生成一次?构造函数和属性都会被EF重复调用,不宜应用(演示:略)。留神:不倡议在Entity(须要映射到数据库的实体类)的构造函数和属性中退出业务逻辑办法如何避免被屡次调用? //领会:异样应用的场景 if (!string.IsNullOrEmpty(ValidationCode)) { throw new InvalidOperationException( $"在ValidationCode已有值的状况下(以后值为:{ValidationCode}),试图再次生成"); }课间作业: ...

December 27, 2020 · 1 min · jiezi

关于react.js:我为什么选择React而不选择Vue

目前前端三大支流框架有:React、Vue、Angular,他们在各自特定的场景下应用都十分杰出。其中,Vue是不错的渐进式JavaScript库,更易于款式开发构建UI。而我更偏向于抉择React,因为React具备独特劣势: React函数式编程理念使代码更优雅和正当谨严的单向数据流设计,不便构建大型简单稳固的单页面利用丰盛的技术生态圈,领有世界范畴内各大技术社区反对不便配合ReactNative开发跨终端利用 React函数式编程让代码更优雅正当函数式编程是用函数的组合来进行编程,先申明函数,而后调用函数,每一步都有返回值,通过抽出每一步逻辑运算形象,封装在函数中。再将函数组合来编写程序。例如:计算平均值百分比,咱们能够拆分为三个函数,一个是计算平均值,一个是计算百分比,一个是综合调用的函数,通过函数嵌套函数的形式,使得代码更优雅,更有利于复用。 React应用函数式编程思维使代码更优雅和正当,更有利于组件化、模块化开发。React的每个组件就是函数生成,页面的渲染过程实质就是函数的嵌套调用过程。React的这种设计对于应用来说十分不便,例如以下子组件嵌套子组件再嵌套子组件示例:子组件中嵌套子组件调用模式始终都是雷同的。父组件调用子组件都只须要思考传递的参数props,而子组件只须要思考传入的参数。 谨严的单向数据流设计,不便构建大型简单稳固的单页面利用React的数据流始终是单向设计的,严格遵循数据驱动DOM。这样的益处是,升高了组件相互通信的代码耦合度,数据流更清晰,调试更不便。大型简单单页面利用始终是企业的难题,传统形式开发都不可能很好的保护。而应用React为根底的技术栈,可能不便地拆分模块、组件,再配合Redux数据流治理,可能高效构建利用。事实证明,这种React、Redux的大型简单单页面我的项目构建计划,曾经在各大互联网公司失去利用和倒退。 丰盛的技术生态圈,领有世界范畴内各大技术社区反对React是由Facebook公司开发的高品质现代化前端框架,具备很高的权威性和专业性,在世界范畴内失去各大技术社区反对,包含国内的技术社区。比方,npm官网、淘宝cnpm社区等都有很丰盛的生态。泛滥的开发者独特添砖加瓦,开源共享,丰盛了技术生态圈,让咱们不便学习和应用基于React的组件、插件,缩小开发成本,进步开发效率。在国内,由阿里巴巴公司开发的基于React根底开发的Antd组件库深受各大互联网企业好评,开箱即用,为减速国内中小企业的中台化、信息化推动起到了重要作用。 不便配合ReactNative开发跨终端利用以后互联网公司的一个重要难题问题是:如何缩小老本、高效的进行跨终端利用开发。也就是说,互联网公司都心愿可能开发iOS、Android、H5利用。React配合ReactNative库可能不便地开发跨终端利用。ReactNative设计原理上和React统一,应用了React技术栈,就曾经有了根底,再配合ReactNative就能一套代码,编译生成多端利用。ReactNative不便泛滥公司疾速高效开发App,升高研发老本,进步了生产力,缩小了开发工夫。 React、Vue发展趋势React的发展趋势更重视函数式编程。以后从16.7版本当前,呈现了Hook函数钩子的思维,只能是React函数式的组件能力应用。这一个性很显著,React心愿将函数式编程施展极致,更优更好地我的项目开发。乏味的是,这里呈现了useMemo函数,像极了Vue中的computed的作用,这里React就是借鉴了Vue的动静监听变量的模式。 Vue的发展趋势为更重视了我的项目标准化、谨严化。在Vue3中曾经开始应用了TypeScript代替不够严格的JavaScript写法。而引入TypeScript这一点是借鉴了React的可能深度交融TypeScript更谨严开发的教训。 React、Vue发展趋势表明,两种框架相互吸取,舍短取长,都是为了可能更好地进行利用开发。 如何正确抉择框架面对React、Vue,咱们应该怎么选。这里提供一些思路: 小型偏重于我的项目如果是偏重于UI展示,更多的款式开发,举荐应用Vue。施展Vue模板款式的劣势。具备简单的数据逻辑利用如中台化我的项目,倡议应用React。单向数据流的模式可能防止数据逻辑谬误。大型简单单页面我的项目,举荐React。再配合如Redux、Mbox等状态治理库,组件化、模块化开发,无效治理。写在最初React、Vue都是杰出的前端框架,都有各自的一席之地。React框架的函数式编程理念、谨严的单向数据流设计、丰盛的技术生态圈以及不便开发跨终端利用具备更大劣势。咱们只有依据应用场景、业务需要、技术实现等综合因素抉择最适宜的框架,能力施展最大的劣势,进步生产力。 结尾本期就分享到这里,我是小编南风吹,专一分享好玩乏味、离奇、实用的开源我的项目及开发者工具、学习资源!心愿能与大家独特学习交换,欢送关注我的公众号【Github导航站】。 往期举荐3000多人拜访一个html文件,多少宽带才足够撑持 程序员接私活必备后盾框架,不必反复造轮子,网友:太好用了! 还在从头到尾撸我的项目?这6个SpringBoot我的项目用好了,事倍功半! 厉害了,这款程序员代码补全工具,让你的编程效率飞起来! 「00后缩写黑话翻译器」登上GitHub热榜,中年网民终于能看懂年轻人的awsl 太酷了!这款开源安卓投屏软件,让你工作游戏两不误!

December 25, 2020 · 1 min · jiezi

关于react.js:搭建-Nextjs-TS-Antd-Redux-Storybook-企业级项目脚手架

前言⭐ Nextjs-TS-Antd-Redux-Storybook-Jest-Starter 之所以有该我的项目呢,是因为日常可能本人须要练手其余 Next.js 我的项目,又不想每次都重新配置一遍,但基于强迫症失常企业级我的项目该有的配置感觉不能少了,于是就想开搞一个通用脚手架模板。 说起 Next.js,8 月份写了一篇文章手把手带你入门 NextJs(v9.5),次要是因为网上大部分 Next.js 是旧版本 v7.x 的教程,于是写个较新的 9.5 版,没想到 10 月就出了 Next.js 10,措手不及,不过更新局部次要是图片优化等,能够照样看。 该我的项目也是想把日常工作中我感觉实际比拟好的点加进来,也打算依据该我的项目继续跟进良好标准和最新库版本。当然,到具体业务场景的话脚手架必定多少须要改,但指标心愿能升高批改的老本,起码根本配置得搞好。 该脚手架次要库和版本: Next.js 10.xReact 17.xTypeScript 4.xAnt Design 4.xStyled-components 5.xStorybook 6.x 初始化 Next.js 模板npx create-next-app nextjs-ts-redux-antd-starter增加 TypeScript 反对根目录下新建tsconfig.json文件,此时运行yarn dev,会看到它提醒咱们装置类型库 yarn add --dev typescript @types/react @types/node顺便把@types/react-dom也装上 装置之后,再运行yarn dev, 会在根目录主动生成next-env.d.ts文件,且tsconfig.json有了默认配置,这里我再对配置稍加改变。 具体能够参考 TS 官网看配置项: { "compilerOptions": { "baseUrl": ".", "paths": { "src/*": [ "src/*" ] }, "target": "es5", "module": "esnext", "strict": true, "allowJs": true, // 容许编译js文件 "jsx": "preserve", // 在 .tsx文件里反对JSX "noEmit": true, // 不输入文件 "lib": [ "dom", "dom.iterable", "esnext" ], // TS须要援用的库,即申明文件 "esModuleInterop": true, // 容许export=导出,由import from导入 "moduleResolution": "node", // 模块解析策略,ts默认用node的解析策略,即绝对的形式导入 "allowSyntheticDefaultImports": true, // 容许从没有设置默认导出的模块中默认导入 "isolatedModules": true, // 将每个文件作为独自的模块 "resolveJsonModule": true, // 容许把json文件当做模块进行解析 "skipLibCheck": true, // 跳过所有申明文件的类型查看 "forceConsistentCasingInFileNames": true // 不容许对同一文件应用不统一大小写的援用 }, "include": [ "next-env.d.ts", "**/*.ts", "**/*.tsx" ], "exclude": [ "node_modules", ".next", "dist" ]}而后革除洁净目录,把styles, pages只留下一个index.js即可, 并将index.js重命名为index.tsx ...

December 25, 2020 · 7 min · jiezi

关于react.js:React2认识JSX语法格式

前言React框架举荐应用的DOM语法格局为JSX语法,属于一种JavaScript扩大,React应用JSX来形容用户界面。咱们能够粗略的认为JSX是JavaScript和HTML的联合,然而在理论的应用过程中还有肯定的细节区别。本文就率领大家零碎的学习JSX语法的格局。 一、JSX语法的根本用法1、应用变量定义JSX元素const element=<div>你好,React!</div>; 这里须要留神,上述代码不是JavaScript字符串,所以没有用任何引号引住;也不是HTML代码。而是JSX语法格局。 React利用的最小单位是“元素”,JSX语法格局就是React举荐用来申明元素的。 2、应用变量定义嵌套的JSX元素对于互相嵌套的JSX元素,JSX语法举荐应用()扩住。 const ulElement=( <ul> <li>第一名</li> <li>第二名</li> </ul>) 应用()扩住嵌套的JSX元素,让格局更加清晰。从理论的操作来看,不书写()也是能够的。 3、在JSX元素中应用变量在JSX元素中应用变量必须应用{}扩住,变量能够用于JSX元素的内容中,也能够用与JSX元素的HTML属性取值上。 let name='张三';const strongElement=<strong>你好,{name}</strong>let url='https://www.baidu.com';const link=<a href={url}>百度一下</a> 4、在JSX元素中调用函数对于具备return返回值的函数,JSX元素能够像应用变量一样,利用{}扩住对函数进行调用。 function getSum(a,b){ return a+b;}let a=10,b=20;const sum=<div>{a}+{b}={getSum(a,b)}</div> 上述几种状况中举的案例元素(element、ulEelement、strongElement、link、sum)都能够间接用在ReactDOM。render()办法的第一个参数中,充当向第二个参数所指的DOM节点中放入的元素。以sum为例,代码如下所示。 ReactDOM.render( sum, document.querySelector('#app')); 二、JSX元素的语法规定JSX元素在书写时还要留神下列语法规定: JSX元素必须具备一个惟一的根节点。JSX元素中标记的class属性取值必须应用className属性。JSX元素中标记的style属性取值必须用两个大括号扩住,即style={{}}。JSX代码中标记外部的正文必须用{}扩住,标记内部的正文不能用{}扩住。JSX代码中的标记必须成对或者有结尾标识。请大家仔细阅读下列代码: const element=( /*一个残缺的JSX元素:本正文没有在任何标记外部,所以不必{}扩住*/ <div> {/*惟一的根节点:本正文在标记外部,必须用{}扩住*/} <div className="top"> {/*className属性的应用*/} {/*style属性的应用必须是双大括号*/} <div style={{width:'1200px',height:'40px',backgroundColor:'#3385ff'}}> 欢送学习React框架。 <img src=”images/01.jpg” /> {/*标记必须有结尾标识*/} </div> </div> </div>);ReactDOM.render( element, document.querySelector('#app')); 上述代码在浏览器中运行,能够从开发人员工具的Elements选项卡中看到下列如图所示的构造。 从图中能够看得出,id属性取值为app的div和class属性取值为top的div之间,有一个空的div。这是因为为了满足JSX元素必须具备一个惟一的根节点,而设置的最外层的div标记对。为了不让最外层的根节点显示在DOM构造中,React倡议应用React.Fragment作为所有JSX元素最外层的根节点。代码该为如下格局。 const element=( /*一个残缺的JSX元素:本正文没有在任何标记外部,所以不必{}扩住*/ <React.Fragment> {/*惟一的根节点:本正文在标记外部,必须用{}扩住*/} <div className="top"> {/*className属性的应用*/} {/*style属性的应用必须是双大括号*/} <div style={{width:'1200px',height:'40px',backgroundColor:'#3385ff'}}> 欢送学习React框架。 <img src=”images/01.jpg” /> {/*标记必须有结尾标识*/} </div> </div> </ React.Fragment >); 这时再看开发人员工具的Elements选项卡,React.Fragment标记地位是没有任何标记对的。 ...

December 24, 2020 · 2 min · jiezi

关于react.js:转载React-Hooks-中的闭包问题

前言明天中午在领完盒饭,吃饭的时候,正吃着深海鳕鱼片,蘸上番茄酱,那美味,几乎无以言表。忽然产品急匆匆的跑过来说:“明天需要能上线吧?”我突然虎躯一震,想到本人遇到个问题迟迟找不到起因,怯怯的答复道:“能...能吧...”,产品听到‘能’这个字便哼着小曲扬长而去,留下我独自一人,面对着曾经变味的深海鳕鱼片...一遍又一遍的想着问题该如何解决... 一、从JS中的闭包说起JS的闭包实质上源自两点,词法作用域和函数以后值传递。 闭包的造成很简略,就是在函数执行结束后,返回函数,或者将函数得以保留下来,即造成闭包。 对于词法作用域相干的知识点,能够查阅《你不晓得的JavaScript》找到答案。 React Hooks中的闭包和咱们在JS中见到的闭包并无不同。 定义一个工厂函数createIncrement(i),返回一个increment函数。每次调用increment函数时,外部计数器的值都会减少i。 function createIncrement(i) { let value = 0 function increment() { value += i console.log(value) } return increment}const inc = createIncrement(10)inc() // 10inc() // 20复制代码createIncrement(10) 返回一个增量函数,该函数赋值给inc变量。当调用inc()时,value 变量加10。 第一次调用inc()返回10,第二次调用返回20,依此类推。 调用inc()时不带参数,JS 依然能够获取到以后 value 和 i 的增量,来看看它是如何工作的。 原理就在 createIncrement() 中。当在函数上返回一个函数时,就会有闭包产生。闭包捕捉了词法作用域中的变量 value 和 i。 词法作用域是定义闭包的内部作用域。在本例中,increment() 的词法作用域是createIncrement()的作用域,其中蕴含变量 value 和 i。 无论在何处调用 inc(),甚至在 createIncrement() 的作用域之外,它都能够拜访 value 和 i。 闭包是一个能够从其词法作用域记住和批改变量的函数,不论执行的作用域是什么。 二、React Hooks中的闭包通过简化状态重用和副作用治理,Hooks 取代了基于类的组件。此外,咱们能够将反复的逻辑提取到自定义 Hook 中,以便在应用程序之间重用。Hooks 重大依赖于 JS 闭包,然而闭包有时很辣手。 ...

December 24, 2020 · 3 min · jiezi

关于react.js:就antd4x写一个多级嵌套的表单

代码在codesandbox,点击跳转查看 antd4.x之后,针对form表单,齐全的进行了重构,应用形式和之前有极大的差异,在此写个多级嵌套的表单,做相熟用。

December 23, 2020 · 1 min · jiezi

关于react.js:React1初识React框架

前言React框架在古代前端开发的我的项目中越来越罕用,该框架的语法结构也深深的影响着其余框架在设计时的思路和理念。本专栏从这篇文章开始,以零根底登程,一步步总结和解说React框架的应用。 一、搭建React工作环境首先咱们先来将React工作环境搭建起来。要想让React工作起来,须要用到下列三个库: react.development.js:React外围库。react-dom.development.js:React操作DOM的库。babel.min.js:将JSX语法转换为JavaScript语法的库。上述三个库大家能够去React的官网进行下载。除此之外,咱们还须要创立一个用于书写React代码的js文件,能够命名为index.js。 接下来咱们要将上述js文件依照程序一个个的加载到HTML文档中。因为本文临时应用非工程化的办法运行React我的项目,所以临时须要手动将js文件加载到HTML文档中。 HTML文档的代码如下所示。 <html> <head> <script type="text/javascript" src="js/react.development.js"></script> <script type="text/javascript" src="js/react-dom.development.js"></script> <script type="text/javascript" src="js/babel.min.js"></script> <script type="text/babel" src="js/index.js"></script> </head> <body></body></html>上述代码须要留神以下两点: 留神1:独立的index.js文件须要在加载时将script标记对的type属性取值为“text/babel”,而不是“text/javascript”。留神2:这样的形式运行React我的项目,须要借助WebStorm或VS Code这样的编辑器,在编辑器自带的内置服务器的帮忙下能力失常启动我的项目。 二、第一个React程序搭建好了React工作环境,咱们来实现第一个React程序,即在浏览器的页面中显示一个一级题目,题目内容为“Hello,React!” 1、首先,在HTML文档中设置一个div标记对作为React我的项目中DOM元素的总容器。会应用Vue.js的同学能够将这个div了解为“挂载点”。同时还要为这个div标记对设置一个id属性或class属性,以保障在index.js文件中能够不便的援用该节点。 <body> <div id=“app”></div></body>2、其次,在index.js文件中输出下列代码: ReactDOM.render( <h1>Hello,React!</h1>, document.querySelector("#app"))ReactDOM.rander()办法是React的外围办法,该办法的格局如下所示。 ReactDOM.rander(JSX代码,DOM节点)上述代码中的h1标记实现的内容其实是JSX语法的代码,而不是HTML语法的代码,只管它们临时长得很像。第二个参数应用document.querySelector()办法指定了一个DOM节点,也就是body标记对外部的id属性取值为app的那个div。 ReactDOM.render()办法有以下两个次要性能: 将JSX代码转换为HTML格局的标记对。将转换的HTML格局的标记对插入到指定的DOM节点外部。3、了解了上述代码的概念,当初能够在webStorm编辑器中执行该我的项目了。如果大家在编写React代码时发现webStorm编辑器顶部有一个修长条提醒,如下图所示。 这条修长的提醒内容为:Switch language version to React JSX,中文翻译为 切换语言版本为React JSX。右侧有两个选项:Switch示意切换,Dismiss示意不予理睬。 这里倡议大家抉择“Switch”,否则编辑器因为无奈正确的辨认JSX语法格局而呈现多处语法错误提醒。 三、初步意识JSX语法:React框架对于DOM节点的生成采纳了JSX语法格局,这是一种专门用于React的DOM节点生成模式。从实质上说,能够了解为HTML标记对和JavaScript语言的这一种联合。 本节咱们对JSX语法进行一个初步的意识,下一篇文章会为大家具体的解说JSX语法的要求。 上面这个例子,咱们只做一个数组,利用JSX语法格局将数组中的元素在页面中渲染为一个无序列表。代码如下所示。 let list=[‘张三’,‘李四’,……];ReactDOM.render( <div> <ul> { list.map(item=>{ return <li>{item}</li> }) } </ul> </div>, document.querySelector("#app"))根据上述代码,咱们能够得出无关JSX语法的以下论断: JSX语法中的HTML局部仍然采纳标记对书写。JSX语法中的JavaScript须要用{}进行包裹。对数组的遍历只能应用数组的办法(例如:map()),不能应用for循环。*总结本文是React系列教程的第一篇文章,次要为大家解说了React我的项目的搭建,意识了JSX语法的根本格局,学习了ReactDOM.render()办法的应用。今天会为大家零碎的解说JSX语法的书写格局。 对于作者小海前端,具备18年Web我的项目开发和前后台培训教训,在前端畛域著有较为零碎的培训教材,对Vue.js、微信小程序开发、uniApp、React等全栈开发畛域都有较为深的造诣。入住Segmentfault,心愿可能更多的结识Web开发畛域的同仁,将Web开发鼎力的进行遍及。同时也违心与大家进行深刻的技术研究和商业单干。

December 23, 2020 · 1 min · jiezi

关于react.js:react中使用webpack的import异步加载组件的实现

1、asyncComponent函数(惊天函数):函数很好了解,loadComponent参数示意须要代码切割的门路,函数返回值是一个react组件,组件外部帮你做好了then()办法的操作。 import React from 'react'export const asyncComponent = loadComponent => ( class AsyncComponent extends React.Component { state = { Component: null, } componentWillMount() { if (this.hasLoadedComponent()) { return; } loadComponent() .then(module => module.default) .then((Component) => { this.setState({ Component }); }) .catch((err) => { console.error(`Cannot load component in <AsyncComponent />`); throw err; }); } hasLoadedComponent() { return this.state.Component !== null; } render() { const { Component } = this.state; return (Component) ? <Component {...this.props} /> : null; } });2、在react中应用 ...

December 20, 2020 · 1 min · jiezi

关于react.js:助力ssr使用concent为nextjs应用加点料

开源不易,感激你的反对,❤ star concent^_^ 序言nextjs是一个十分风行的 React 服务端渲染利用框架,它很轻量,简略易上手,社区沉闷,所以当咱们应用react写一个须要ssr(server side render)的利用的话,根本都会首选nextjs,concent是一个新生代的react状态治理计划,它内置依赖收集零碎,同时兼具备0入侵、可预测、渐进式、高性能的特点,并提供了lifecyle、composition api等灵便的api且写法超级简略,让你轻松驾驭超大规模的react利用。 Hello next这里咱们将应用create-next-app命令来装置一个根底的next示例利用 npx create-next-app hello-next执行结束后,能够看到一个如下的目录构造 |____public|____pages| |____ _app.js // next利用默认的根组件| |____index.js // 默认首页| |____api // api路由文件| | |____hello.js 之后咱们在我的项目根目录执行npm run dev将看到一个由next驱动的ssr默认首页 Hello concent这里咱们将应用create-react-app命令来装置一个根底的concent示例利用 npx create-react-app hello-concent --template concent-ts执行结束后,能够看到一个如下的目录构造 |____index.tsx|____App.tsx|____types // store的类型定义处|____features // 性能组件列表| |____counter // counter性能| | |____Counter.tsx // counter组件| | |____model // counter模型(蕴含state,reducer,computed)|____models // 其它全局通用的模型定义|____configs进入我的项目目录执行npm i,而后执行npm start即可看到一个默认的计数器页面 你也能够点击这里在线理解和编辑它。当然了在已有的我的项目里集成concent里也超级简略,因为它无需顶层提供Provider,只须要提前配置好模型即可。 import { run } from 'concent';run({ // 定义一个counter模型 counter: { state: { num: 1, bigNum: 10 }, reducer: { add(payload, moduleState) { return { num: moduleState + 1 }; }, async asyncAddBig() { await new Promise(resolve => setTimeout(resolve, 1000)); return { bigNum: moduleState + 10 }; } }, computed: { doubleNum: ({ num }) => num * 2, // 仅当num发生变化才触发此函数 } }})之后就能够全局即插即用啦,类组件和函数组件都能够用同样的形式去读取数据或调用办法,敲重点啦,如果ui处是有条件语句管制是否要生产状态或衍生数据的话,举荐提早解构的写法,这样能够让concent在每一轮渲染结束后收集到视图对数据的最小粒度依赖 ...

December 19, 2020 · 3 min · jiezi

关于react.js:必须收藏这13个优秀React-JS框架没用过就很离谱

如果你正在应用React.js或React Native创立用户界面,能够试一试本文举荐的这些框架。React.js和React Native是风行的用户界面(UI)开发平台,且都是开源技术。在StackOverflow的2019年开发人员考察中,它们在冀望度和使用率方面都有很高的排名。React.js是Facebook在2011年作为一个JavaScript库开发而成的,目标是满足跨平台、动静和高性能UI的需要;而Facebook在2015年公布的React Native则是用来基于JavaScript构建原生应用程序的。 上面列举了13个精选的React JavaScript框架;它们全都是开源的——前11个(就像React那样)是依据MIT许可受权的,后两个则是依据Apache 2.0受权。 1.Creat React App由Facebook开发人员带来的这款命令行界面是所有React Native我的项目的必备框架。因为Create React App(https://github.com/facebook/create-react-app)易于应用,让你省掉了手动设置和配置利用的麻烦,从而节俭了大量工夫和精力。 只需一条简略的命令,所有就都准备就绪,你就能轻松创立React Native我的项目了。你能够用它来构建目录和文件,该框架还包含用于构建、测试和公布应用程序的工具。 Install package$ npm install -g create-react-native-web-app Run create-react-native-web-app <project-directory>$ create-react-native-web-app myApp cd into your <project-directory>$ cd myApp Run Web/Ios/Android developmentWeb$ npm run web IOS (simulator)$ npm run ios Android (connected device)$ npm run android 为什么抉择Create React App带有配置包、转译器和测试器的一流开发工具利用构造中没有配置,也没有多余的文件。巩固的开发栈。卓有成效的疾速开发工具。2.Material Kit ReactMaterial Kit React(https://github.com/creativetimofficial/material-kit-react)受到了谷歌的Material Design零碎启发,是构建React UI组件的绝佳抉择。这个库最大的长处是它提供了许多组件,这些组件能够组合在一起生成难以置信的成果。库中有超过1000个齐全编码的组件,每个组件都有独自的层,这些层都在文件夹中分门别类组织好了。这意味着你有着成千上万种抉择。如果你想获取灵感,或与某人分享想法或概念,也有几个示例页面可用。 装置Material Kit$ npm install @material-ui/core 实现import React from 'react'; import Button from '@material-ui/core/Button'; const App = () => (   <Button variant="contained" color="primary">     Hello World   </Button> ); ...

December 18, 2020 · 3 min · jiezi

关于react.js:引入图片资源404显示-object20Module-404-Not-Found

新建的react我的项目,并且webpack配置是本人自定义的。 一开始这样引入,报GET http://localhost:3000/assets/logo192.png 404 (Not Found): <img src='./assets/logo192.png' alt="logo"/>而后在网上搜寻一番,用了require语法引入,而后就报这个谬误GET http://localhost:3000/[object%20Module] 404 (Not Found): <img src={require('./assets/logo192.png')} alt="logo" />原来是webpack配置的问题在url-loader外部封装了file-loader而file-loader在新版本中esModule属性默认为true 即默认应用ES模块语法导致了援用图片文件的形式和以前的版本不一样,引入门路扭转了,天然找不到图片。上面是批改webpack配置 { test: /\.(jpe?g|png|gif)$/i, // 图片文件 use: [ { loader: 'url-loader', options: { limit: 10240, fallback: { loader: 'file-loader', options: { name: 'img/[name].[contenthash:8].[ext]',+ esModule: false } },+ esModule: false } } ], exclude: /node_modules/}【参考】React 加载本地图片在应用Webpack打包本地img图片文件时图片加载失败

December 17, 2020 · 1 min · jiezi

关于react.js:漫谈-React-Fiber

本文作者:葛星背景React 实现了应用 Virtual DOM 来形容 UI 的形式,通过比照两棵树的差别最小化的更新 DOM,这样使得用户的代码变的傻瓜,然而同时也来带了一些问题。这个外围的问题就在于 diff 计算并非是收费的,在元素较多的状况下,整个 diff 计算的过程可能会继续很⻓工夫,造成动画丢帧或者很难响应用户的操作,造成用户体验降落。为什么会呈现这个问题,次要是因为上面两个起因: React < 15 的版本始终采纳 Stack Reconciler 的形式进行 UI 渲染(之所以叫 Stack Reconciler 是绝对于Fiber Reconciler 而言) , 而 Stack Reconciler 的实现是采纳了递归的形式,咱们晓得递归是无奈被打断,每当有须要更新的时候,React 会从须要更新的节点开始始终执行 diff ,这会耗费大量的工夫。浏览器是多线程的,蕴含渲染线程和 JS 线程,而渲染线程和 JS 线程是互斥的,所以当 JS 线程占据大量工夫的时候,UI 的响应也会被 block 住。下面两个起因缺一不可,因为如果 JS 执行, UI 不会阻塞 ,其实用户也不会有所感知。上面让咱们看下比拟常见的性能优化伎俩。 常见的性能优化伎俩个别咱们会采纳上面的形式来优化性能 防抖对函数应用防抖的形式进行优化。这种形式将 UI 的更新推延到用户输出结束。这样用户在输出的时候就不会感觉到卡顿。 class App extends Component { onChange = () => { if (this.timeout) { clearTimeout(this.timeout); } this.timeout = setTimeout( () => this.setState({ ds: [], }), 200 ); }; render() { return ( <div> <input onChange={this.onChange} /> <list ds={this.state.ds} /> </div> ); }}应用 PureComponent || shouldComponentUpdate通过 shouldComponentUpdate 或者 PureComponent 的形式进行优化。这种形式通过浅比照前后两次的 props 和 state 让 React 跳过不必要的 diff 计算。 ...

December 16, 2020 · 4 min · jiezi

关于react.js:如何采用React-Context-Hooks-去做全局状态管理

在业务或者UI交互略微简单一些的我的项目里,都离不开状态治理的问题。不论是从后盾API申请的数据还是页面的UI状态,都须要有一个"Store"帮咱们去做状态治理。通常在我的项目中,咱们会引入 Redux 去负责这样的职责。然而 Redux 要保护大量的模板代码,加上 Redux 通过 connect 这种高阶组件的形式注入 state 和 dispatch 的形式并不直观,减少了了解的复杂度。React从16.8开始,引入了 React Hook,配合 Context API,能够在我的项目中来解决全局状态治理的问题。 React Context + Hooks 状态治理架构咱们先来整体看一下通过 React Context 和 Hooks 进行状态治理的架构图。咱们把形成架构的每个负责不同职责的节点称为"性能单元",上面列出了架构图中波及的所有性能单元和对应的职责: React Context:负责全局状态治理,通过提供的 Context API,能够进行状态的读写。每个 Context 都会生成 Context.Provider 和 Context.Consumer Context.Provider:为生产组件提供存储的 context 值,通常存储全局 state 和用来散发 action 的 dispatch 办法Context.Consumer:能够订阅 context 的变更,引入 Hooks 后,能够应用 useContext 来读取 context,因而在实现中不须要关怀 Context.ConsumerComponent:组件的概念不须要多讲,在基于组件的架构中,是用来形成 React 利用最根底的性能单元Action:Action 是组件收回的告诉,用于形容要产生的事件或者变动Reducer:用于响应 Action,来解决 state 的变动,基于 Action 和旧的 state 返回新的 state在架构图中,形容性能单元之间的交互的"S"和"D",别离示意 state 和 dispatch 办法,其中 ...

December 14, 2020 · 2 min · jiezi