重构javascript_JavaScript代码清理:如何重构以使用类

重构javascript

In smaller React projects, keeping all of your component methods in the components themselves works well. In medium-sized projects, you may find yourself wishing you could get those methods out of your components and into a “helper”. Here, I’ll show you how to use a Class (instead of exporting individual functions and variables) to organize your code.

在较小的React项目中,将所有组件方法保留在组件本身中会很好地工作。 在中型项目中,您可能会希望自己可以将这些方法从组件中提取出来,并放入“帮助器”中。 在这里,我将向您展示如何使用类(而不是导出单个函数和变量)来组织代码。

Note: I work in React so that’s the example we’ll discuss here.

注意 :我在React中工作,这就是我们将在这里讨论的示例。

典型重构 (Typical refactor)

In a typical refactor, you’d take a function on the component and move it to another helper.

在典型的重构中,您将在组件上使用一个函数并将其移至另一个帮助器。

From:

从:

const MyComponent = () => {
  const someFunction = () => 'Hey, I am text'
  return (
    <div>
      {someFunction()}
    </div>
  )
}

To:

至:

import { someFunction } from 'functionHelper.js'
const MyComponent = () => {
  return (
    <div>
      {someFunction()}
    </div>
  )
}

and

export const someFunction = () => 'Hey, I am text'

This example is really silly, but you see where we’re going:

这个例子确实很愚蠢,但是您会看到我们要去的地方:

  1. Take your functions and copy them over to a separate file

    接受您的功能并将其复制到单独的文件中
  2. Import them and call them as normal.

    导入它们并正常调用它们。

When things get complicated, though, you’ll have to pass in a bunch of stuff to those functions — objects, functions for manipulating state, and so on. Today I ran into a problem where I wanted to extract three functions out of a component and they all required the same inputs (a resource and a function to update the resource). There’s got to be a better way…

但是,当事情变得复杂时,您必须将大量东西传递给这些函数-对象,用于操纵状态的函数,等等。 今天,我遇到了一个问题,我想从一个组件中提取三个函数,它们都需要相同的输入(一个resource和一个用于更新resource的函数)。 一定有更好的方法……

用类重构 (Refactoring with a class)

I made a big demo for this post. You can see the code on Github. The initial commit shows all of the functionality inside the main component (App.js) and the subsequent commits refactor the code to use a class.

我为这篇文章做了一个大型演示。 您可以在Github上查看代码。 初始提交显示了主要组件( App.js )内的所有功能,随后的提交将代码重构为使用类。

You can run this yourself and do whatever you want to it. Remember to yarn install.

您可以自己运行它,并做任何您想做的事情。 切记要yarn install

We start with a component that “fetches” an object (mimicking the way we might do this from an API) with certain attributes on it: repeat (number of boxes), side (height and width), text, color. We then have a number of ways we manipulate the view — changing the color, updating the text, and so on. After each change, we display a message.

我们从一个组件开始,该组件“获取”一个对象(模仿我们从API进行操作的方式),并带有某些属性:重复(框数),侧面(高度和宽度),文本,颜色。 然后,我们可以通过多种方式来操作视图-更改颜色,更新文本等。 每次更改后,我们都会显示一条消息。

For instance, here’s our change width and height method:

例如,这是我们的更改宽度和高度方法:

changeSide = side => {
  const obj = {...this.state.obj, side}
  this.fetchObject(obj);
  this.setState({ message: `You changed the sides to ${side} pixels!` });
}

We might have a number of other methods that require similar actions — or perhaps very different methods. We might start thinking about extracting this code to a helper. Then we would create a different method to call the setState action and we’d have to pass it, this.fetchObject, the object in state, and the side we are getting as an argument to the method. If we have several similar methods, that’s a whole lot of passing parameters and maybe it’s not actually that helpful (or readable).

我们可能还有许多其他方法需要类似的操作,或者可能是非常不同的方法。 我们可能会开始考虑将这些代码提取给助手。 然后,我们将创建一个不同的方法来调用setState操作,并且必须将它传递给this.fetchObject ,处于状态的对象以及作为该方法的参数要获得的side 。 如果我们有几种类似的方法,那是很多传递参数,实际上可能没有那么有用(或可读性)。

Instead we can use a class, complete with a constructor method:

相反,我们可以使用带有构造函数方法的类:

export default class ObjectManipulator {
  constructor( { object, fetchObject, markResettable, updateMessage, updateStateValue } ) {
    this.fetchObject = fetchObject;
    this.markResettable = markResettable;
    this.updateMessage = updateMessage;
    this.updateStateValue = updateStateValue;
  }

  changeSide = ( object, side ) => {
    const newObject = { ...object, side };
    this.fetchObject(newObject);
    this.updateMessage(`You changed the sides to ${side} pixels!`);
    this.markResettable();
    this.updateStateValue('side', side);
  };
};

This allows us to create an object whose functions we may call inside of our main component:

这使我们可以创建一个对象,可以在主要组件内部调用其功能:

const manipulator = new ObjectManipulator({
  object,
  fetchObject: this.fetchObject,
  markResettable: this.markResettable,
  updateMessage: this.updateMessage,
  updateStateValue: this.updateStateValue,
});

This creates an object manipulator — an instance of our ObjectManipulator class. When we call manipulator.changeSide(object, '800') it will run the changeSide method we define above. There’s no need to pass in updateMessage or any of the other methods — we pick them up from the constructor, when we created the instance.

这将创建一个对象manipulator -我们的ObjectManipulator类的实例。 当我们调用manipulator.changeSide(object, '800') ,它将运行上面定义的changeSide方法。 无需传入updateMessage或任何其他方法-创建实例时,我们从构造函数中选择它们。

You can imagine that this becomes really useful if we have a lot of these methods to deal with. In my case, I needed to call .then(res => myFunction(res) after everything I was trying to extract. Defining myFunction on the class instance instead of passing it to each function saved me a lot of code.

您可以想象,如果我们要处理许多这样的方法,那么这将变得非常有用。 以我ng myFunct ,在尝试提取所有内容后,我需要调用.then(res => myFunction(r es)。在类实例上ng myFunct而不是将其传递给每个函数可以节省很多代码。

保持一切井井有条 (Keeping everything organized)

This method of organization can be really helpful to keep everything in its place. For instance, I have an array of colors that I map over to get the color buttons you see in the example. By moving this constant into the ObjectManipulator, I can make sure it doesn’t clash with any other colors in the rest of my app:

这种组织方法对于将一切保持在原位非常有用。 例如,我映射了一组颜色以获得在示例中看到的颜色按钮。 通过将此常量移到ObjectManipulator ,我可以确保它不会与应用程序其余部分中的任何其他colors发生冲突:

export default class ObjectManipulator {
  [...]

  colors = ['blue', 'red', 'orange', 'aquamarine', 'green', 'gray', 'magenta'];
};

I can use manipulator.colors to grab the right colors for this page, whereas there might be a global colors constant that is used for something else.

我可以使用manipulator.colors来为该页面获取正确的颜色,而可能会有一个用于其他内容的全局colors常量。

参考文献 (References)

Good old Mozilla Class docs

好的老Mozilla类文档

翻译自: https://www.freecodecamp.org/news/javascript-code-cleanup-how-you-can-refactor-to-use-classes-3948118e4468/

重构javascript

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值