日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

react 日历组件_anujs1.5.1支持React.Suspense与lazy

發布時間:2023/12/3 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 react 日历组件_anujs1.5.1支持React.Suspense与lazy 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

React16是一個實驗版本,除了測試它的新fiber架構外,還添加了大量新功能。其他React.Suspense與React.lazy就是重磅中的重磅。

隨著前端的APP化,不斷集成功能,頁面越來越大,bundle size以MB為單位,我們需要拆分代碼,實現動態化加載非首屏功能。比日歷,城市選擇器,評論組件等等。

動態加載,在javascript模塊加載規范中已經有草案,并且被webpack, rollup所支持

import('../components/Hello').then(Hello => {console.log(<Hello />); });

相當于(setTimeout模擬異步加載組件):

new Promise(resolve =>setTimeout(() =>resolve({// 來自另一個文件的函數式組件default: function render() {return <div>Hello</div>}}),3000) ).then(({ default: Hello }) => {console.log(<Hello />); });

React16提供了lazy組件實現這個功能

var {lazy, Suspense} = React;var OtherComponent = lazy(()=>{return new Promise(resolve =>setTimeout(() =>resolve({default: function Hello() { //export defaultreturn <div>Hello</div>}}),3000))});

上面只是一個方便大量測試的例子,實際需要將 <div>Hello</div> 放到一個文件中,使用import()語法引進來,即

const OtherComponent = React.lazy(() => import('./OtherComponent'));

OtherComponent.js的源碼

export default function Hello(){return <div>Hello</div> }

接著我們實現將動態功能加進組件樹,就是所謂的條件渲染。這個功能由React.Suspense提供。在框架不提供這功能的情況下,我們需要找一個父組件,將這組件動態掛上去:

class MyComponent extends Component {constructor() {super();this.state = {};// 動態加載import('./OtherComponent').then(({ default: OtherComponent }) => {this.setState({ OtherComponent });});}render() {const { OtherComponent } = this.state;return (<div>{/* 條件渲染 */}{ OtherComponent && <OtherComponent /> }</div>);} }

但光是這樣還是不行的,因為單純的動態加載,會引起頁面抖動,我們需要loading將這個突兀的顯示給緩解一下。于是這render需要改成

render() {const { OtherComponent } = this.state;return (<div>{OtherComponent ? <OtherComponent />: <Loading />}</div>);}

如果有了Suspense組件,我們就簡單了,不需要入侵已有的組件,并且有地方掛這個loading。

<Suspense fallback={<Loading />}><OtherComponent /></Suspense>

需要注意的是,lazy組件外面必須包著一個Suspense組件。從框架層面對用戶體驗提出了強制要求。

下面是一個完整的例子

<!DOCTYPE html> <html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width"> <!--<script src="https://cdn.bootcss.com/react/16.7.0-alpha.2/umd/react.development.js"></script><script src="https://cdn.bootcss.com/react-dom/16.7.0-alpha.2/umd/react-dom.development.js"></script> --><script src="./dist/React.js"></script> <script type='text/javascript' src="./lib/babel.js"></script></head><body><div id='root' class="root"></div><script type='text/babel'>var { lazy, Suspense } = React; var OtherComponent = lazy(() => {return new Promise(resolve =>setTimeout(() =>resolve({default: function render(props) {//export defaultreturn <div>Hello,{props.name}</div>;}}),3000)); }); var valueRef = React.createRef() class App extends React.Component {constructor(props){super(props)this.state = {name: "ruby"}}updateName(){var name = valueRef.current.value;this.setState({name})}render() {return (<div><p><input ref={valueRef} onChange={this.updateName.bind(this)} value={this.state.name} />{new Date-0}</p><Suspense fallback={<div>loading...</div>}><OtherComponent name={this.state.name} /></Suspense></div>);} }ReactDOM.render(<App />, document.getElementById("root"));</script></html>

最后說一下實現,React官方是通過lazy組件主動拋錯,給上面Suspense組件接住的hack方式實現的

https://github.com/facebook/react/blob/master/packages/react-reconciler/src/ReactFiberWorkLoop.js#L907-L1057

lazy組件被讀取時

https://github.com/facebook/react/blob/master/packages/react-reconciler/src/ReactFiberLazyComponent.js

React官方投入了近500行代碼實現的,

再看一下anujs如何實現的。

anujs的Suspense是異常簡單,就是一個虛擬組件,甩手掌柜,總是渲染它的孩子。它只負責掛loading。

function Suspense(props){return props.children }export {Suspense }

lazy組件就是將用戶函數,再包一層,封到一個LazyComponent組件中,它會根據用戶的promise決定是返回上層的suspense組件的fallback屬性,還是延期加載回來的組件。

import { miniCreateClass, isFn, get } from "react-core/util"; import { Component } from "react-core/Component"; import { createElement } from "react-core/createElement"; import { Suspense } from "./Suspense";var LazyComponent = miniCreateClass(function LazyComponent(props, context) {this.props = props;this.context = context;this.state = {component: null,resolved: false}var promise = props.render();if(!promise || !isFn(promise.then)){throw "lazy必須返回一個thenable對象"}promise.then( (value) =>this.setState({component: value.default,resolved: true}))}, Component, {fallback(){//返回上層Suspense組件的fallback屬性var parent = Object(get(this)).returnwhile(parent){if( parent.type === Suspense){return parent.props.fallback}parent = parent.return}throw "lazy組件必須包一個Suspense組件"},render(){return this.state.resolved ? createElement(this.state.component) : this.fallback()} }); function lazy(fn) {return function(){return createElement(LazyComponent, {render: fn})} } export {lazy }

最后歡迎大家使用anujs 。一個迷你React框架,支持react16 的所有新特性,可以用于小程序中。

RubyLouvre/anu?github.comnpm i anujs

總結

以上是生活随笔為你收集整理的react 日历组件_anujs1.5.1支持React.Suspense与lazy的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。