javascript - 改进 React Ui 组件

标签 javascript reactjs material-ui

我需要有关改进 UI 组件的建议,该组件接收包含所有数据类型(即字符串、整数、 bool 值、数组和对象)的对象并显示所有数据类型。 对象的示例。 PS:这个对象也在codesandbox链接中提供。

const data = {
  foo1: {},
  foo9: true,
  foo3: "some random string",
  foo4: "some random string",
  created_at: {
    $date: 1637368143.618
  },
  sources: {
    foo1: {
      first_date: {
        $date: 1637368143.618
      }
    }
  },
  download: {
    status: "pending"
  },
  foo8: "some random string",
  foo5: "some random string",
  foo7: ["sms"],
  foo10: "some random string",
  foo11: {
    bar5: 0,
    bar3: null,
    bar1: null,
    bar2: 0
  },
  foo28: ["some random string", "some random string2"],
  foo19: "some random string"
};

当前我循环遍历该对象并将数据显示在卡片中。

Object.entries(objSorted).map(([key, value])

但首先将对象按以下顺序排序到信息:字符串、整数或 bool 值、数组和对象。

这是codesandbox 的链接。 here

PS:这更多的是一个建议而不是一个问题,我对代码没有任何问题。我只想知道当前显示这些数据的方式是否良好且用户友好(我不这么认为,这就是我问的原因)。如果您认为有更好的方法,您可以评论或编辑codesandbox或创建新的codesandbox。

最佳答案

你的直觉是正确的!我们可以通过以类似于您提到的方式分解所有内容来使这一点更容易理解。我们真正想要的是更好的关注点分离。所有这些挥手细节都消失了,但概念将是您随身携带的。

  1. 您有数据。
  2. 对数据进行排序。
  3. 循环第 2 步的输出并渲染卡片。
  4. 利润?

步骤 1/2。你有数据。为什么不在渲染之前消化它呢?有很多方法可以做到这一点,但为了可读性,让我们创建一个钩子(Hook)并对下游消费者保持良心。如果我们的 ObjectExtract 组件具有格式良好的数据,我们可以使它变得更简单...并且我们可以记录结果,以便我们的摘要数据被缓存,因此不会重新计算渲染。

const useCardData = (data) => {
  return useMemo(() => {
    const entries = Object.entries(data)
        .map(([key, value]) => {
          let type = "unknown";

          if (Array.isArray(key)) {
              type = "array";
          } else if (typeof value === "boolean") {
              type = "boolean";
          } else if { ... };

          return { type, value, key, priority: getTypeSortId(type) };
        })
        .sort((x, y) => x.priority - y.priority)

    return entries;
  }, [data]);
};

我们尽可能多地消化我们的数据。稍后需要 key 因为使用索引作为键几乎不是您想要的,因为当顺序更改时,React 使用键来跟踪应如何移动行。数组中的数字索引实际上并不能描述记录的唯一性。想象一下对记录进行排序,索引 1 在排序之前和之后可能意味着完全不同的事情,并且您的数据可能会也可能不会正确显示。我们使用对象属性名称作为唯一键,因为对象在不允许重复键方面做得很好。

第 3 步。让我们使用 Hook 并渲染数据。

const CardRenderer = ({ data }) => {
  const cards = useCardData(data);

  return (
    <>
      {cards.map((thing) => {
        switch (thing.type) {
          case "boolean":
            return <BooleanCard key={thing.key} data={thing} />;
          case "string":
            return <StringCard key={thing.key} data={thing} />;
          case "...":
            return ...;
        }
      }}
    </> 
  )
};

由于我们的数据格式良好,我们可以简单地使用开关循环它。请注意我们如何创建更小的卡片组件来处理每种特定情况,而不是在一个组件中定义所有情况及其结果。分离关注点。 bool 卡关心 bool 值的外观等。这使得测试变得 super 容易,因为您可以单独测试每张卡,然后测试我们的 CardRenderer 的输出以确保其输出是合理的。

第 4 步:盈利。我们将所有内容分解为组件。每个部分只关心特定的职责,这使得将事物粘合在一起变得很容易。它使其可组合。我们可以单独测试每个部分并确保其做正确的事情。我们可以制作一些像这样非常复杂的东西,同时隐藏每个个体的复杂性。

我描述的是SOLID 。链接中的示例是 PHP 语言,但我认为您会明白要点。我们可以而且应该在 React 中使用相同的模式来构建真正酷的东西,同时管理更酷的东西日益复杂的情况。

关于javascript - 改进 React Ui 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70043041/

相关文章:

javascript - 如何从 gatsby-config.js 中获取动态数据?

javascript - 在 React.js 中更改父级的状态

javascript - MUI Select - 悬停时更改图标背景颜色

reactjs - 如何在 React 中禁用 Material UI 日期选择器的下划线?

javascript - React Material UI OutlinedInput 不显示错误信息

HTML5 getImageData 的 javascript 内存泄漏

javascript - 使用 Django 提供随机图像

javascript - jquery 汉堡菜单有什么问题?

javascript - 使用 jQuery 将图像链接更改为 "#"

javascript - React.addons.classSet 不是 React js 的函数