博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
react hooks使用_使用Hooks动态加载React组件
阅读量:2505 次
发布时间:2019-05-11

本文共 10033 字,大约阅读时间需要 33 分钟。

react hooks使用

Dynamic sites need flexibility. Flexibility results in more code. More code means increased maintenance time. How can we keep our sites maintainable and fast?

动态站点需要灵活性。 灵活性导致更多代码。 更多代码意味着增加维护时间。 我们如何保持网站的可维护性和快速性?

One of the ways to load sites faster is to send browsers less JavaScript to process.

更快加载网站的方法之一是向浏览器发送较少JavaScript进行处理。

We can shave off a few bytes by lazy-loading React components (“components” hereafter). Such a dynamic loading can also make code maintainable (but not always).

我们可以通过延迟加载React组件(以下简称“组件”)来节省一些字节。 这种动态加载还可以使代码可维护(但并非始终如此)。

We’ll take a look at how to load components dynamically, and check out some more advanced usage. Lastly, we’ll load only the components being used.

我们将研究如何动态加载组件,并检查一些更高级的用法。 最后,我们将仅加载正在使用的组件。

目录 (Table of Contents)

动态加载组件 (Loading Components Dynamically)

Suppose you are showing a different component depending on a property, subredditsToShow.

假设您根据属性subredditsToShow显示了一个不同的组件。

Try out

在尝试

import React from 'react';import shortid from 'shortid';import LearnReactView from './views/learnreactView';import ReactView from './views/reactView';import JavaScriptView from './views/javascriptView';import NullView from './views/NullView';export default function App({ subredditsToShow }) {  const subredditElementList = subredditsToShow.map(    subreddit => {      switch (subreddit) {        case 'reactjs':          return 
; case 'learnreactjs': return (
); case 'javascript': return (
); default: return (
{`"r/${subreddit}" - not implemented`}
); } } ); return
{subredditElementList}
;}

We’ll use to generate unique keys because we don’t know what can be a key for a component.

我们将使用生成唯一键,因为我们不知道什么可以作为组件的键。

Whenever we want to handle a new subreddit, we need to

每当我们要处理新的subreddit时,我们都需要

  • Add a new import - importing even unused ones.

    添加新的导入 -甚至导入未使用的导入。

  • Update the switch component - produces unmaintainable code.

    更新开关组件 -生成无法维护的代码。

We can prevent those issues by loading components dynamically per subreddit and removing the switch statement as shown below using useEffect and useState.

我们可以通过每个subreddit动态加载组件并使用useEffectuseState删除如下所示的switch语句来避免这些问题。

Try out

在尝试

import React, { lazy, useEffect, useState } from 'react';import shortid from 'shortid';const importView = subreddit =>  lazy(() =>    import(`./views/${subreddit}View`).catch(() =>       import(`./views/NullView`)    )  );export default function App({ subredditsToShow }) {  const [views, setViews] = useState([]);    useEffect(() => {    async function loadViews() {      const componentPromises =         subredditsToShow.map(async subreddit => {          const View = await importView(subreddit);          return 
; }); Promise.all(componentPromises).then(setViews); } loadViews(); }, [subredditsToShow]); return (
{views}
);}

Let’s break down the code above.

让我们分解上面的代码。

  • importView imports a view dynamically. It returns a NullView () for an unmatched subreddit.

    importView动态导入视图。 它为不匹配的subreddit返回NullView ( )。

  • We then store components in views to render after we finished importing in useEffect.

    然后,在将useEffect导入完成后,我们将组件存储在views以进行渲染。

  • loadViews inside useEffect imports views and stores them in the state with setViews.

    useEffect loadViews导入视图,并将其存储在setViews状态setViews

  • Lastly, we need to wrap views with ) with a fallback to show when the components in views is.

    最后,我们需要使用来包装视图,并使用一个后备广告来显示views的组件何时存在。

We now know how to load components dynamically so let’s take a look at a more advanced scenario.

现在,我们知道了如何动态加载组件,因此让我们看一个更高级的场景。

处理不同的数据类型 (Handling Different Data Types)

We can load a different “view” dynamically by matching against a data property. Suppose that we’re dealing with the following JSON data.

我们可以通过匹配数据属性来动态加载不同的“视图”。 假设我们正在处理以下JSON数据。

{  "data": {    "children": [      {        "data": {          "subreddit": "reactjs",          "title": "Really good tutorial on using hooks",          "url": "..."        }      },      {        "data": {          "subreddit": "javascript",          "title": "[Re-Post] React Hook Form",          "url": "..."        }      },      {        "data": {          "subreddit": "pics",          "title": "Dogs vs. Cats",          "url": "..."        }      }    ]  }}

It’s from an actual response from

它来自的实际响应

We can handle different subreddits by loading only views we’ve implemented.

通过仅加载已实现的视图,我们可以处理不同的subreddit

Try out

在尝试

import React, { lazy, useEffect, useState } from 'react';import shortid from 'shortid';const importView = subreddit =>  lazy(() =>    import(`./views/${subreddit}View`).catch(() =>      import(`./views/NullView`)    )  );const searchSubreddit = async query =>  fetch(    `https://www.reddit.com/search.json?q=${query}`  ).then(_ => _.json());export default function App({ subredditsToShow }) {  const [views, setViews] = useState([]);  const extractData = response =>    response.data.children.map(({ data }) => data);  useEffect(() => {    async function loadViews() {      const subredditsToShow = await searchSubreddit(        'react hooks'      ).then(extractData);      const componentPromises = subredditsToShow.map(        async data => {          const View = await importView(data.subreddit);          return (            
); } ); Promise.all(componentPromises).then(setViews); } loadViews(); }, [subredditsToShow]); return (
{views}
);}

The differences from the are:

与的区别是:

  • We are now dealing with an object, data, instead of the subreddit string.

    现在,我们正在处理对象data ,而不是subreddit字符串。

  • Passing data down to each dynamic view, <View key={shortid.generate()} {...data} />

    将数据向下传递到每个动态视图, <View key={shortid.generate()} {...data} />

Each view now gets a copy of the data as a prop and uses it anyway it wants to.

现在,每个视图都会获得data的副本作为道具,并随时使用它。

views/reactjsView.js
views / reactjsView.js
import React from 'react';import Layout from './Layout';import styled, { css } from 'styled-components';const Container = styled.article`  display: flex;  flex-direction: column;`;export default ({ subreddit, title, url }) => (  

{title}

{`r/${subreddit}`}

-> Visit the site
);
views/javascriptView.js
views / javascriptView.js
import React from 'react';import Layout from './Layout';import styled, { css } from 'styled-components';const Container = styled.article`  display: flex;  flex-direction: row;  background-color: rgba(0, 0, 0, 0.1);  padding: 2rem;  & > * {    padding-left: 1rem;  }`;export default ({ subreddit, title, url }) => (  

{title}

({`r/${subreddit}`})

-> Visit the site
);

Loading components provided no benefit as we loaded them automatically.

加载组件没有任何好处,因为我们会自动加载它们。

Let’s see how we can send less JavaScript to the browser by loading the components only when a user takes an action.

让我们看看如何仅在用户执行操作时通过加载组件将更少JavaScript发送到浏览器。

按需加载组件 (Loading Components on Demand)

So far, we’ve loaded components automatically without a performance improvement.

到目前为止,我们已经自动加载了组件,而性能没有得到改善。

We can do better by sending JavaScript only when needed when a user performs an action.

通过仅在用户执行操作时在需要时发送JavaScript,我们才能做得更好。

Suppose that we need to show different types of charts for the following data.

假设我们需要为以下数据显示不同类型的图表。

const data = [  {    id: 'php',    label: 'php',    value: 372,    color: 'hsl(233, 70%, 50%)'  },  {    id: 'scala',    label: 'scala',    value: 363,    color: 'hsl(15, 70%, 50%)'  },  {    id: 'go',    label: 'go',    value: 597,    color: 'hsl(79, 70%, 50%)'  },  {    id: 'css',    label: 'css',    value: 524,    color: 'hsl(142, 70%, 50%)'  },  {    id: 'hack',    label: 'hack',    value: 514,    color: 'hsl(198, 70%, 50%)'  }];

We can load the site fast without sending unused JavaScript and load charts only when needed.

我们可以快速加载网站,而无需发送未使用JavaScript并仅在需要时加载图表。

Try out

在尝试

import React, { lazy, useState } from 'react';import shortid from 'shortid';const importView = chartName =>  lazy(() =>    import(`./charts/${chartName}`)      .catch(() => import(`./charts/NullChart`))  );const data = [ ... ];const ChartList = ({ charts }) =>  Object.values(charts).map(Chart => (    
));export default function App() { const [charts, setCharts] = useState({}); const addChart = chartName => { if (charts[chartName]) return; const Chart = importView(chartName); setCharts(c => ({ ...c, [chartName]: Chart })); }; const loadPieChart = () => addChart('Pie'); const loadWaffleChart = () => addChart('Waffle'); return (
);}
  • importView is the same as it was except for the component location.

    除了组件位置之外, importView与其他importView相同。

  • ChartList iterates an object where the name is a chart name and the value is the imported component.

    ChartList迭代一个对象,其中名称是图表名称,而值是导入的组件。

  • The App state, charts, is an object to track components that are already loaded.

    App状态charts是一个对象,用于跟踪已加载的组件。

  • addChart imports a chart by name dynamically and add to the charts state, which is what we render.

    addChart通过名称动态导入一个图表并添加到charts状态,这就是我们呈现的内容。

  • loadPieChart and loadWaffleChart are convenience methods and you can memoize with .

    loadPieChartloadWaffleChart是方便的方法,您可以使用 。

  • return renders two buttons, and we need to wrap charts with Suspense.

    return呈现两个按钮,我们需要用Suspense包装图表。

结语 (Wrapping up)

Now you know how to load React components dynamically on demand with the help of hooks.

现在您知道了如何在钩子的帮助下按需动态加载React组件。

A possible use case for dynamic loading is for a dashboard site where you load features only when a user accesses them.

动态加载的可能用例是在仪表板站点,您仅在用户访问要素时才在其中加载要素。

工作演示 (Working Demos)

翻译自:

react hooks使用

转载地址:http://ulhgb.baihongyu.com/

你可能感兴趣的文章
Bootstrap栅格系统
查看>>
自然语言工程师要求
查看>>
Leetcode 452.用最少数量的箭引爆气球
查看>>
【转】Linux设备驱动之Ioctl控制
查看>>
实例说明>
查看>>
日常理财
查看>>
ng-bind-html在ng-repeat中问题的解决办法
查看>>
制定document.getElementByClassName()
查看>>
UVA-315 无向图求割点个数
查看>>
Python学习_4_购物车
查看>>
ubuntu开机自启动
查看>>
【WXS数据类型】Number
查看>>
canvas学习笔记 ---- 1
查看>>
纪念开博客的第一天_(:з」∠)_
查看>>
WechatHelper
查看>>
测试SDWebImage淡入淡出效果在UITableView中的重用显示问题
查看>>
[控件] ChangeColorLabel
查看>>
将位图导入为ArcGIS面要素
查看>>
前自增和后自增的区别
查看>>
Linux 基本操作
查看>>