动态创建react代码_react代码生成 - CSDN
精华内容
参与话题
  • Code Splitting不是构建React应用程序的必要步骤。但是如果您对Code Splitting是什么以及如何帮助更大的React应用程序感到好奇,请随时跟进。 代码拆分 在处理React.js单页应用程序时,应用程序有增长的趋势。应用...

    Code Splitting不是构建React应用程序的必要步骤。但是如果您对Code Splitting是什么以及如何帮助更大的React应用程序感到好奇,请随时跟进。

    代码拆分

    在处理React.js单页应用程序时,应用程序有增长的趋势。应用程序(或路径)的一部分可能会导入大量首次加载时不必要的组件。这会损害我们应用的初始加载时间。

    您可能已经注意到,.js在我们构建应用程序时,Create React App将生成一个大文件。这包含我们的应用程序所需的所有JavaScript。但是,如果用户只是加载登录页面进行登录; 我们用它加载应用程序的其余部分是没有意义的。在我们的应用程序非常小的时候,这不是一个问题,但它成为一个问题。为了解决这个问题,Create React App有一个非常简单的内置方法来分割我们的代码。不出所料,这个功能被称为Code Splitting。

    创建React App(从1.0开始)允许我们使用import()提案动态导入部分应用程序。你可以在这里阅读更多相关信息。

    同时,动态import()可用于我们的React应用程序中的任何组件; 它与React Router配合得非常好。因为,React Router根据路径确定要加载哪个组件; 只有当我们导航它们时才动态导入这些组件是有意义的。

    代码拆分和反应路由器v4

    React Router用于为您的应用程序设置路由的常用结构如下所示。

    /* Import the components */
    import Home from "./containers/Home";
    import Posts from "./containers/Posts";
    import NotFound from "./containers/NotFound";
    
    /* Use components to define routes */
    export default () =>
      <Switch>
        <Route path="/" exact component={Home} />
        <Route path="/posts/:id" exact component={Posts} />
        <Route component={NotFound} />
      </Switch>;

    我们首先导入将响应我们路线的组件。然后使用它们来定义我们的路线。该Switch组件呈现与路径匹配的路由。

    但是,我们在顶部静态导入路径中的所有组件。这意味着,无论匹配哪条路线,都会加载所有这些组件。为了实现Code Splitting,我们将只想加载响应匹配路由的组件。

    创建异步组件

    为此,我们将动态导入所需的组件。

    添加以下内容src/components/AsyncComponent.js

    import React, { Component } from "react";
    
    export default function asyncComponent(importComponent) {
      class AsyncComponent extends Component {
        constructor(props) {
          super(props);
    
          this.state = {
            component: null
          };
        }
    
        async componentDidMount() {
          const { default: component } = await importComponent();
    
          this.setState({
            component: component
          });
        }
    
        render() {
          const C = this.state.component;
    
          return C ? <C {...this.props} /> : null;
        }
      }
    
      return AsyncComponent;
    }

    我们在这里做了几件事:

    1. asyncComponent函数采用了一个参数; 一个function(importComponent),当被调用时将动态导入给定的组件。当我们使用时,这将更有意义asyncComponent
    2. componentDidMount,我们只需调用importComponent传入的函数。并将动态加载的组件保存在状态中。
    3. 最后,如果组件已完成加载,我们会有条件地渲染组件。如果不是,我们只是渲染null。但是null,您可以渲染加载微调器而不是渲染。当您的应用程序的一部分仍在加载时,这会给用户一些反馈。

    使用异步组件

    现在让我们在路线中使用这个组件。而不是静态导入我们的组件。

    import Home from "./containers/Home";
    

    我们将使用它asyncComponent来动态导入我们想要的组件。

    const AsyncHome = asyncComponent(() => import("./containers/Home"));

    重要的是要注意我们在这里没有进行导入。我们只是在创建组件时asyncComponent动态地传递一个函数。import()AsyncHome

    另外,我们在这里传递一个函数似乎很奇怪。为什么不传入一个字符串(比如说./containers/Home)然后在import()里面做动态AsyncComponent?这是因为我们想要明确说明我们动态导入的组件。Webpack基于此分割我们的应用程序。它查看这些导入并生成所需的部分(或块)。

    然后我们将AsyncHome在路线中使用该组件。AsyncHome当路由匹配时,React Router将创建组件,然后动态导入Home组件并像以前一样继续。

    <Route path="/" exact component={AsyncHome} />

    现在让我们回到我们的Notes项目并应用这些更改。

    src/Routes.js在更改之后,您应该看起来像这样。

    import React from "react";
    import { Route, Switch } from "react-router-dom";
    import asyncComponent from "./components/AsyncComponent";
    import AppliedRoute from "./components/AppliedRoute";
    import AuthenticatedRoute from "./components/AuthenticatedRoute";
    import UnauthenticatedRoute from "./components/UnauthenticatedRoute";
    
    const AsyncHome = asyncComponent(() => import("./containers/Home"));
    const AsyncLogin = asyncComponent(() => import("./containers/Login"));
    const AsyncNotes = asyncComponent(() => import("./containers/Notes"));
    const AsyncSignup = asyncComponent(() => import("./containers/Signup"));
    const AsyncNewNote = asyncComponent(() => import("./containers/NewNote"));
    const AsyncNotFound = asyncComponent(() => import("./containers/NotFound"));
    
    export default ({ childProps }) =>
      <Switch>
        <AppliedRoute
          path="/"
          exact
          component={AsyncHome}
          props={childProps}
        />
        <UnauthenticatedRoute
          path="/login"
          exact
          component={AsyncLogin}
          props={childProps}
        />
        <UnauthenticatedRoute
          path="/signup"
          exact
          component={AsyncSignup}
          props={childProps}
        />
        <AuthenticatedRoute
          path="/notes/new"
          exact
          component={AsyncNewNote}
          props={childProps}
        />
        <AuthenticatedRoute
          path="/notes/:id"
          exact
          component={AsyncNotes}
          props={childProps}
        />
        {/* Finally, catch all unmatched routes */}
        <Route component={AsyncNotFound} />
      </Switch>
    ;

    非常酷,只需进行一些更改,我们的应用程序就可以进行代码分割。并且不会增加更多的复杂性!这就是我们src/Routes.js以前的样子。

    import React from "react";
    import { Route, Switch } from "react-router-dom";
    import AppliedRoute from "./components/AppliedRoute";
    import AuthenticatedRoute from "./components/AuthenticatedRoute";
    import UnauthenticatedRoute from "./components/UnauthenticatedRoute";
    
    import Home from "./containers/Home";
    import Login from "./containers/Login";
    import Notes from "./containers/Notes";
    import Signup from "./containers/Signup";
    import NewNote from "./containers/NewNote";
    import NotFound from "./containers/NotFound";
    
    export default ({ childProps }) =>
      <Switch>
        <AppliedRoute
          path="/"
          exact
          component={Home}
          props={childProps}
        />
        <UnauthenticatedRoute
          path="/login"
          exact
          component={Login}
          props={childProps}
        />
        <UnauthenticatedRoute
          path="/signup"
          exact
          component={Signup}
          props={childProps}
        />
        <AuthenticatedRoute
          path="/notes/new"
          exact
          component={NewNote}
          props={childProps}
        />
        <AuthenticatedRoute
          path="/notes/:id"
          exact
          component={Notes}
          props={childProps}
        />
        {/* Finally, catch all unmatched routes */}
        <Route component={NotFound} />
      </Switch>
    ;

    请注意,我们不是为顶部的所有容器执行静态导入,而是创建这些函数,这些函数将在必要时为我们执行动态导入。

    现在,如果您使用构建应用程序npm run build; 你会看到代码分裂在行动中。 

    创建React应用程序代码拆分构建屏幕截图

    每个.chunk.js文件都是import()我们拥有的不同动态调用。当然,我们的应用程序非常小,分割的各个部分根本不重要。但是,如果我们用来编辑笔记的页面包含一个富文本编辑器; 你可以想象它会如何增长。不幸的是,它会影响我们应用的初始加载时间。

    现在,如果我们使用部署我们的应用程序npm run deploy; 当我们在演示中浏览时,您可以看到浏览器按需加载不同的块。

     

    而已!只需进行一些简单的更改,我们的应用程序就可以完全设置为使用Create React App所具有的代码拆分功能。

    下一步

    现在这似乎很容易实现,但您可能想知道如果导入新组件的请求花费太长时间或失败会发生什么。或者您可能想要预加载某些组件。例如,用户在您的登录页面上即将登录,并且您想要预加载主页。

    上面提到过,您可以在导入过程中添加加载微调器。但我们可以更进一步,解决其中一些边缘情况。有一个很好的高阶组件可以很好地完成这些工作; 它被称为反应可加载的

    您需要做的就是安装它。

    $ npm install --save react-loadable
    

    使用它而不是asyncComponent我们上面的那个。

    const AsyncHome = Loadable({
      loader: () => import("./containers/Home"),
      loading: MyLoadingComponent
    });

    并且AsyncHome使用与以前完全一样。在这里,MyLoadingComponent会是这个样子。

    const MyLoadingComponent = ({isLoading, error}) => {
      // Handle the loading state
      if (isLoading) {
        return <div>Loading...</div>;
      }
      // Handle the error state
      else if (error) {
        return <div>Sorry, there was a problem loading the page.</div>;
      }
      else {
        return null;
      }
    };

    它是一个简单的组件,可以优雅地处理所有不同的边缘情况。

    展开全文
  • react生成动态内容

    千次阅读 2018-09-06 08:44:42
    代码结构: index.js import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App2 from './App2'; ReactDOM.render(&lt;App2 /&gt;, document.getElementById...

    效果:

     

    代码结构:

    index.js

    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App2 from './App2';
    
    ReactDOM.render(<App2 />, document.getElementById('root'));
    

    Todo2.js

    import React from 'react';
    
    export default class Todo2 extends React.Component {
     
      constructor(props) {
        super(props);
      }
      deleteThis(){
      	let {deleteUl,index}=this.props;
      	if(window.confirm("确认删除?")){
      		deleteUl(index);
      	}
      }
      editThis(){
      	let{editUl,index}=this.props;
      	editUl(index);
      }
       render() {
        return (
        	<React.Fragment>
    	      <div>
    	      	<ul  className="list">
    		      	<li>
    		      		{this.props.content_name}
    	      		</li>
    	      		<li>--</li>
    	      		<li>
    		      		{this.props.content_post}
    	      		</li>
    	      		<li>
    		      		<button onClick={this.editThis.bind(this)}>编辑</button>
    	      		</li>
    	      		<li>
    					<button onClick={this.deleteThis.bind(this)} >删除</button>
    	      		</li>
    	      	</ul>
    	      	
    	      </div>
    	    </React.Fragment>
        );
      }
    }

    App2.js

    import React from 'react';
    import Todo2 from './Todo2';
    export default class App2 extends React.Component {
      constructor(props) {
        super(props);
       	this.state={
       		input_name:'',
        	input_post:'',
        	list:[
        		{"name":"张三","post":"校长"},
        		{"name":"王五","post":"主任"}
        	],
        	editStatus:-1,
        	
       	}
      }
      deleteUl(e,index){
      	let list=this.state.list;
      	list.splice(index,1);
          this.setState({
            list:list 
          });
      }
      editUl(index,e){
      	let list=this.state.list;
      	
      	this.setState({
      		input_name:list[index].name,
      		input_post:list[index].post
      		})
      	this.state.editStatus=index;
      }
      input_name_change(e){
      	 this.setState({   
          input_name:e.target.value 
        })
      }
      input_post_change(e){
      	 this.setState({   
          input_post:e.target.value 
        })
      }
      addUser(e){
      	let user={"name":this.state.input_name,"post":this.state.input_post};
      	let list=this.state.list;
      	if(this.state.input_name.length!=0 && this.state.input_post.length!=0){
      		console.log(this.state.input_name);
      		if(this.state.editStatus!=-1){
      		list[this.state.editStatus].name=this.state.input_name;
      		list[this.state.editStatus].post=this.state.input_post;	  
    
    	  	}else{
    	  		list.push(user);
    	  		}
    	  	this.setState({
    		  	list:list,
    		  	input_name:'',
    		  	input_post:''
    		  	})
    	  	}else{
    	  		alert("姓名和职务不能为空");
    	  	}
      	
      	
      }
      render() {
        return (
          <div className="App2">
          	<div className="form">
          		姓名:<input value={this.state.input_name} onChange={this.input_name_change.bind(this)}/>
          		<br />
          		职务:<input value={this.state.input_post} onChange={this.input_post_change.bind(this)}/>
          		<br />
          		<button onClick={this.addUser.bind(this)} >添加</button>
          	</div>
    
          	<div className="content">
          		<ul>
          			{
          				this.state.list.map((item,index)=>{
          					return(
          						<Todo2
          							 key={index} 
                     				 content_name={item['name']} 
                     				 content_post={item['post']}
                     				 index={index} 
                     				 deleteUl={this.deleteUl.bind(this)}
                     				 editUl={this.editUl.bind(this)}
          						 />
          					)
          				})	
          			}
          		</ul>
          	</div>
          </div>
        );
      }
    }

    index.css

    body {
      margin: 0;
      padding: 0;
      font-family: sans-serif;
    }
    
    .content .list li{
    	float: left;
    	list-style: none;
    	width: 200px;
    	height: 40px;
    	line-height: 40px;
    
    
    }
    .content .list li button{
    	display: inline-block;
    	border: 0px;
    	background-color: #029AE5;
    	color: white;
    	width: 80px;
    	height: 40px;
    
    
    }
    .content .list {
    	overflow: hidden;
    	cursor: pointer;
    	background-color: #DF6464;
    	
    
    }

    其中事件绑定this可以写在构造其中,

    this.input_name_change=this.input_name_change.bind(this);

    react渲染时最外层需要用div标签包起来,如果不想显示那层div,在外层加上一个<React.Fragment>标签即可。

    展开全文
  • 需要根据某变量,如列表元素,const values = [{'text':'123'},{'text':'456'}],动态绘制页面元素,如上述列表元素需要绘制出两个 下拉框+输入框 的组合。 2、问题: 一般绘制页面代码如下: import React, { ...

    1、背景

    需要根据某变量,如列表元素,const values = [{'text':'123'},{'text':'456'}],动态绘制页面元素,如上述列表元素需要绘制出两个 下拉框+输入框 的组合。

    2、问题:

    一般绘制页面代码如下:

    import React, { Component } from 'react';
    class A extends Component {
        // xxx;
        
        render() {
            return <div>
                        <div><select/><input/></div>
                        <div><select/><input/></div>
                   </div>;
        }
    }

    但是现在需要根据values渲染界面,独立出来一个函数来拼接jsx元素,动态加入render函数返回值,但是jsx元素没有类似append这样的元素追加函数可以使用。所以借助于其他方式来实现该功能。

    3、解决

    借助map函数,及jsx语法实现如下:

    import React, { Component } from 'react';
    class A extends Component {
        // xxx;
        
        genElements = (values) => {
            if(!values){
                return null;
            }
            return values.map((value, index) => {
                return this.addEle(value, index);
            });
        }
    
        addEle = (value, index) => {
            // 需要指定key 不重复,否则会报警告
            return <div key={index}><select/><input value={value} /></div>;
        }
    
    
        render() {
            const values =  [{'text':'123'},{'text':'456'}];
            return <div>
                        {this.genElements(values)}
                   </div>;
        }
    }

    这样即可实现元素的动态添加。

     

    相关阅读:

    二级循环嵌套元素:https://blog.csdn.net/qq_16591861/article/details/86527336

    展开全文
  • 众所周知,在使用webpack打包react应用时,webpack将整个应用打包成一个js文件,当用户访问首屏时,会一次性加载整个js文件,当应用的规模变得越来越庞大的时候,首屏渲染速度变慢,影响用户体验。 于是,webpack...

    众所周知,在使用webpack打包react应用时,webpack将整个应用打包成一个js文件,当用户访问首屏时,会一次性加载整个js文件,当应用的规模变得越来越庞大的时候,首屏渲染速度变慢,影响用户体验。

    于是,webpack开发了代码分割的特性, 此特性能够把代码分割为不同的bundle文件,然后可以通过路由按需加载或并行加载这些文件。

    代码分割可以用于获取更小的bundle,以及控制资源加载优先级,如果使用合理,会极大影响加载时间。有三种常用的代码分割方法:

    1、拆分入口:使用 entry 配置手动地分割代码。

    2、防止重复:使用 CommonsChunkPlugin 去重和分离chunk。

    3、动态导入:通过模块的内联函数调用来分离代码。本文只讨论动态导入(dynamic imports)的方法。

    动态导入

    当涉及到动态代码拆分时,webpack提供了两个类似的技术。对于动态导入,第一种,也是优先选择的方式是,使用符合ECMA提案的 import() 语法。第二种,则是使用 webpack 特定的 require.ensure。本文使用第一种方式。

    注意:import() 调用会在内部用到promise。如果在旧有版本浏览器中使用 import(),记得使用一个polyfill 库(例如 es6-promise 或 promise-polyfill),来 shim Promise。

    下面结合react-router 4来实现react的代码分割。

    在React应用中实现

    React应用的代码分割需要结合路由库react-router使用,当前react-router的版本是V4,在使用react-router4进行代码分割的路上,社区已经有成熟的第三方库进行了实现,如react-loadable。在此处将介绍如何不借助第三方库实现代码分割。

    此处假设你已经对react、react-router4、webpack有基本的了解,可以搭建简单的开发环境。下面是本项目的基本目录结构:

    项目入口文件src/index.js:

     

    src/App.js:

    在App.js中,引入react-router-dom路由模块,以及路由配置文件routes.js,App组件主要负责通过路由配置遍历生成一系列路由组件。

    下面是路由配置src/routes.js:

    routes.js中配置了路由组件需要的参数,需要注意的是在路由参数中使用了异步组件AsyncComponent,注意这里并没有直接引入组件,而是传递一个函数参数给AsyncComponent,它将在AsyncComponent(() => import('./containers/home'))组件被创建时进行动态引入。

    同时,这种传入一个函数作为参数,而非直接传入一个字符串的写法能够让webpack意识到此处需要进行代码分割。

    使用import()需要使用Babel预处理器和动态import的语法插件(Syntax Dynamic Import Babel Plugin)。由于 import() 会返回一个 promise,因此它可以和ES7的async函数一起使用,使用acync函数需要安装babel-plugin-transform-runtime插件。

    安装babel插件:

    本项目使用的其他babel插件还有babel-core、babel-loader、babel-preset-env、babel-preset-react等,主要用于React的jsx语法编译。

    下面需要编写babel配置文件.babelrc,在根目录下新建.babelrc,配置如下:

    异步组件AsyncComponent

    代码分割的核心部分就是实现AsyncComponent,本项目的AsyncComponent放在src/components/async-component/index.js中,代码如下:

    整个模块是一个高阶组件,返回一个新的组件,传入两个参数,一个是需要动态加载组件的方法,第二个是动态加载时的占位符,占位符的默认参数为一个字符串,也可以传入一个Loading组件。

    在返回的AsyncComponent组件内部,constructor中,初始化一个state为Child,值为null,并定义this.unmount =false,用于表示组件是否被卸载。

    使用acync定义异步方法,componentDidMount中,使用await异步执行传入的第一个参数,用于动态加载当前路由的组件。

    注意:

    当调用ES6模块的import()方法(引入模块)时,必须指向模块的.default值,因为它才是promise 被处理后返回的实际的module对象。

    故此处使用ES6的对象解构获取到模块的default并赋值到Child上。

    然后判断组件被卸载的状态,被卸载即返回。

    下面将Child设置到state上。

    在render方法中,从state中获取Child,然后使用三元运算符判断Child是否存在,存在则渲染Child组件,并传入this.props,否则渲染占位符。

    组件componentWillUnmount时,设置this.unmout为true。

    测试

    现在开始编写一些简单的业务组件用于测试,在containers中新建两个文件夹home和detail,在两个文件夹下编写index.js作为两个路由组件。代码如下:

    containers/home/index.js:

    containers/detail/index.js:

    在根目录下package.json配置启动脚本:

    然后运行npm start启动项目:

    打开浏览器访问localhost:8080

    查看右侧network面板,可以看到页面先加载了main.js和0.js,点击详情按钮跳转到http://localhost:8080/detail

    随后加载了1.js,这样就实现了代码分割,每个路由都是动态加载的。在大型React应用中,将bundle进行细粒度的拆分,可以极大提升首屏渲染速度,提升用户体验。

    展开全文
  • React动态加载组件

    千次阅读 2019-05-09 13:51:10
    查阅react的官网文档,发现两种方式: [[React.lazy](https://reactjs.org/docs/code-splitting.html#reactlazy)和 [loadable-components](https://github.com/smooth-code/loadable-components) ...
  • 在我们的产品中有很多需要点击 或者回调函数执行时 生成DOM 标签 我称之为...但是在React中我们尽量少的使用JQ 理解组件化的概念,那我们怎么利用它本身的某些API和方法来实现我们动态生成DOM的需求呢  我们知道Rea
  • react动态渲染子组件

    千次阅读 2018-03-09 17:13:57
    //例如伪代码infoList: [{ "title": "panel_1", "context": "this is panel_1" }, { "title": "panel_2", "context": "this is panel_...
  • 1、第一种方式 createHtmlCommonFun() { let waterfallLeft = document.getElementById('waterfallLeft'), waterfallRight = document.getElementById('waterfallRight'), _domLeft =...
  • 这几天一直在弄动态修改react-navigation的各种属性的方法,想做成额效果如下: 上面是有一个导航栏的,然后导航栏上面有两个view,就是左边的定位和右边的搜索,然后导航栏的透明度可以动态调整,这里弄了一个text...
  • React16.8组件代码复用的4种方式

    千次阅读 2019-05-24 10:02:11
    react项目开发中经常会遇到有一些代码复用的问题,现介绍几种常见的方式 一、直接把相同的代码复制一份到需要使用的组件中(非常low的方式) 二、创建一个高阶组件,将复用的代码存放到高阶组件中,需要使用的组件中...
  • 基于ReactNative实现动态加载

    千次阅读 2018-12-24 09:41:32
    下载Demo代码之后发现用到了facebook开源的react-native框架。然后打算研究一下是否能模拟动态下发模块的效果。 于是决定从以下几个方面来实现这个过程。 1、服务端——实现首页接口及下载接口 服务端用Spring...
  • React 实现动态添加元素到列表

    千次阅读 2020-07-30 11:48:52
    首先声明一下,大佬请绕道,以下内容为React纯基础,适合小白新手练习Demo,后面会持续更新 做成的效果如下图 知识点梳理: 1 理解React state 2 理解React props 3 掌握父子间的值传递 4 了解ES6语法 直接上代码...
  • react native项目创建

    千次阅读 2017-05-10 13:53:07
    react native项目创建、运行、调试 1、项目命令行创建、运行 react-native init myrnprj1 // 创建工程 cd myrnprj1 react-native start // 开启packager服务--Running packager on port 8081. //浏览器地址栏输入...
  • React创建组件的三种方式及其区别

    千次阅读 2016-11-26 16:58:25
    React创建组件的三种方式及其区别 React推出后,出于不同的原因先后出现三种定义react组件的方式,殊途同归;具体的三种方式: 函数式定义的无状态组件es5原生方式React.createClass定义的组件es6形式的...
  • 只需要创建一个表格,id为videos,react就能将这个表格转换成视频列表,并点击自动播放 index.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <meta ...
  • 在使用create-react-app创建react项目的时候,原始的项目结构是不能够使用less预编译器。 使用 yarn reject暴露配置文件 $ yarn reject $ react-scripts eject NOTE: Create React App 2 supports TypeScript, ...
  • 用React.lazy和Suspense优化React代码打包

    千次阅读 2018-12-27 01:20:34
    戳上方蓝字关注我们吧钟志,2013年加入去哪儿网技术团队,目前在大住宿事业部,技术委员会委员,大前端负责人。个人对移动端技术、工程化有浓厚兴趣。前言为了让网站加载更快,通...
  • React动态增加表单

    千次阅读 热门讨论 2019-11-19 11:25:22
    本人React前端开发,最近赶上一需求 要实现动态添加用户的姓名与联系方式,这个给我难受的啊! Jquery搞了一天 (本人技术有点渣,jquery写的少) ,样式效果引入总出问题,好不容易解决样式了,这动态ID实在是搞...
  • 大多数 React 应用都会使用Webpack或Browserify这类的构建工具来打包文件。打包是一个将文件引入并合并到一个单独文件的过程,最终形成一个 “bundle”。接着在页面上引入该 bundle,整个应用即可一次性加载。 示例...
  • 为什么要动态加载 进入项目后会加载bundle.js,就是所有页面都打包到这里,第一次加载页面就把所有的页面都加载好了。 你进入的是首页,但是它把登录页,详情页。。。全部都加载出来了。 好处是:当你再进入其他...
1 2 3 4 5 ... 20
收藏数 18,573
精华内容 7,429
关键字:

动态创建react代码