您好,登錄后才能下訂單哦!
這篇文章主要介紹了React遠程動態組件怎么實現的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇React遠程動態組件怎么實現文章都會有所收獲,下面我們一起來看看吧。
遠程動態組件庫項目結構如下所示:
. ├── babel.config.js ├── package.json ├── rollup.config.js └── src ├── Button.js ├── Text.js
我們簡單實現了兩個組件 Button
和 Text
:
import React from 'react' export default ({children}) => { return <button style={{color: 'blue'}}>{children}</button> }
import React from 'react' export default ({children}) => { return <span style={{color: 'blue'}}>{children}</span> }
我們使用 rollup 對其進行打包,之所以用 rollup 是因為其打包出來的代碼非常簡潔,方便我們查看,rollup 配置為:
import babel from 'rollup-plugin-babel' import fs from 'fs' const components = fs.readdirSync('./src') export default components.map((filename) => { return { input: `./src/${filename}`, output: { file: `dist/${filename}`, format: 'cjs', }, plugins: [babel()], } })
打包后的結果如下所示:
. ├── dist │ └── Button.js │ └── Text.js
其中 Button.js
如下所示:
'use strict' var React = require('react') function _interopDefaultLegacy(e) { return e && typeof e === 'object' && 'default' in e ? e : {default: e} } var React__default = /*#__PURE__*/ _interopDefaultLegacy(React) var Button = function (_ref) { var children = _ref.children return /*#__PURE__*/ React__default['default'].createElement( 'button', { style: { color: 'blue', }, }, children ) } module.exports = Button
然后我們使用 http-server 在 dist
目錄下開啟一個靜態文件服務,則可以通過 http://localhost:8080/Button.js
獲取到打包后的代碼。
遠程組件庫介紹完畢,接下來介紹業務項目中如何使用。
我們使用 create-react-app
創建一個 React 應用,并新增一個 DynamicComponent
組件:
const DynamicComponent = ({name, children, ...props}) => { const Component = useMemo(() => { return React.lazy(async () => fetchComponent(name)) }, [name]) return ( <Suspense fallback={ <div style={{alignItems: 'center', justifyContent: 'center', flex: 1}}> <span style={{fontSize: 50}}>Loading...</span> </div> }> <Component {...props}>{children}</Component> </Suspense> ) } export default React.memo(DynamicComponent)
這里使用到了 React 中的 Suspense
組件和 React.lazy
方法,關于他們的用法這里不做過多解釋,整個 DynamicComponent
組件的含義是遠程加載目標組件,這個過程該組件會渲染傳入 Suspense
參數 fallback
之中的內容,最后會使用加載成功的組件進行替換。接下來看看 fetchComponent
是如何實現的:
const fetchComponent = async (name) => { const text = await fetch( `http://127.0.0.1:8080/${name}.js?ts=${Date.now()}` ).then((a) => { if (!a.ok) { throw new Error('Network response was not ok') } return a.text() }) const module = getParsedModule(text, name) return {default: module.exports} }
該方法會發起網絡請求得到組件的代碼,并交給 getParsedModule
去解析,最后得到模塊返回。我們來看一下 getParsedModule
是怎么實現的:
const packages = { react: React, } const getParsedModule = (code) => { let module = { exports: {}, } const require = (name) => { return packages[name] } Function('require, exports, module', code)(require, module.exports, module) return module }
這里使用 Function
來運行傳入的代碼,因為打包遠程組件的時候并沒有將 react
庫打包進去,所以這里需要實現 require
這個方法。
我們結合之前打包得到的 Button.js
來看這段代碼,它其實同下面這個代碼是等價的:
const packages = { react: React, } const getParsedModule = (code, moduleName) => { let module = { exports: {}, } const require = (name) => { return packages[name] } ;((require, exports, module) => { 'use strict' var React = require('react') function _interopDefaultLegacy(e) { return e && typeof e === 'object' && 'default' in e ? e : {default: e} } var React__default = /*#__PURE__*/ _interopDefaultLegacy(React) var Button = function (_ref) { var children = _ref.children return /*#__PURE__*/ React__default['default'].createElement( 'button', { style: { color: 'blue', }, }, children ) } module.exports = Button })(require, module.exports, module) return module }
最后我們可以按照如下方式來使用 DynamicComponent
組件:
import DynamicComponent from './DynamicComponent' function App() { return ( <div> <DynamicComponent name='Button'>Click Me</DynamicComponent> <DynamicComponent name='Text'>Remote Component</DynamicComponent> </div> ) } export default App
現在我們嘗試修改遠程動態組件庫中的組件,重新打包后就可以馬上看到修改后的效果了。
關于“React遠程動態組件怎么實現”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“React遠程動態組件怎么實現”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。