agm1984
agm1984

Reputation: 17150

How to modularize JavaScript class (pull methods out of main file, import methods into main file)

Is it possible to pull class methods out of the class in JS? Forgive me, I am functional paradigm, so using React forces me to use classes and this keyword (so far anyway). Some of my components are getting large and I do not want this.

I can't find anything on Google about pulling methods out or modularizing a class.

Is there a way I can just say "get this method from './some_method.js' and use it as if it was declared inside this file&class" without much invasive changes?

Failing that, I'm hypothesizing about making them all functions and pass this into them. That feels pretty dirty, however.

I'd appreciate some guidance to what keywords I need to be looking at, or simply how to move methods out so I don't have 2000 line files that take me 20 minutes to find

toggleFullMenu() {
    this.setState({ menuOpen: !this.state.menuOpen})
}

without pressing CTRL+F. That is my motivation.

I'd also like to know if there are any pro tips about this as relates to constructors. Any warnings from the class inheritance paradigm folks? I simply want the methods to sit by themselves in separate files, but I don't know what I'm looking for. I've never seen people talking about this.

Edit, I just found this in the MDN:

Sub classing with extends

The extends keyword is used in class declarations or class expressions to create a class as a child of another class.

Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes

class Dog extends Animal {
  speak() {
    console.log(this.name + ' barks.');
  }
}

Is this what I need? How would I go about pulling a bunch of extensions in? I don't want a child class though, that doesn't sound like what I am describing.

Upvotes: 1

Views: 694

Answers (3)

bennygenel
bennygenel

Reputation: 24680

Right ahead I can say that Yes you can pull out different methods from other classes or files other than created in your component. There lots of different ways to go and it really depends on your preference. You can go from really simple to really complex structures.

First thing you need to search and learn about (if you don't already know) require() and/or ES6 import and export. You can create stand alone functions or objects and import them into your component to use them. If you have repeating functions that you use in different components or parts of your app this is the way to go.

If I comment on passing this as a parameter, it is not pretty like you said in your question. Rather than passing this, passing required parameters to functions and using callbacks or Promises is the way to go. Another technique you can use is to bind function to this. ES6 arrow functions don't need to be bind since they don't bind their own this.

If you would like to go a little more complex/complicated you can always create your own classes. Class structure can give ability to do more complex things. extends gives you ability to extend (like you can understand from its name) your class methods with others or overwrite them with new ones. For example, Beverages, Snacks, Meats can be classes that extends from Foods class. When you create a custom component you extend a React.Component and then you use its methods.

Another thing to consider is that having a 2000 lines component makes me think that you should also consider separating your components into smaller chunks. Parent/Child component relationship is most common and supported structure in React. If you use this pattern your code will automatically get smaller and it will be much more easier to follow and manage. There are lots of examples on how to pass functions as props to child components and run them in certain conditions with certain parameters and then manipulating parent component's state. You can look for those examples to get better understanding.

I hope these topics will help you to understand couple of thing and show you to where to start.

Upvotes: 2

djfdev
djfdev

Reputation: 6037

You can do so using Function.prototype.bind, so that you have control of the value of this.

In one module, you can export the "method" as a regular function:

// methods.js
export const toggleFullMenu = () => {
  this.setState({ menuOpen: !this.state.menuOpen })
}

And in your component module:

import React from 'react'
import { toggleFullMenu } from './methods'

class SomeComponent extends React.Component {
  constructor () {
    super()
    this.toggleFullMenu = toggleFullMenu.bind(this)
  }

  render () {
    return <button onClick={this.toggleFullMenu}>Click Me</button>
  }
}

The toggleFullMenu function could be bound to other contexts as well, so you could actually share that method across different components.

EDIT: There are many different ways to bind the context of a function, you are not limited to Function.prototype.bind. See this chapter for an explanation of the various ways to do so.

Upvotes: 2

Yoann N
Yoann N

Reputation: 51

Webpack is a fully-featured javascript app bundler. With Webpack you can import / export code like:

export default class CustomerView {
    render() {
        ...
    }
}

and

import CustomerView from './CustomerView'

`

Upvotes: 0

Related Questions