Home > Software engineering >  Reusing React components to handle a different DB collection
Reusing React components to handle a different DB collection

Time:10-28

I have a beginner question about React. I just wrote this component:

class MovieInput extends React.Component {
  constructor(props) {
    super(props);
    firebase.initializeApp(config);
  
    this.state = {
      movies: []
    };
  }

  ....
}

It is working fine, saving data in Firebase under a collection called movies. I am starting to work on a second component looking like this:

class BookInput extends React.Component {
  constructor(props) {
    super(props);
    firebase.initializeApp(config);
  
    this.state = {
      books: []
    };
  }

  ....
}

I can already see that most of the code for the two components is going to be the same, making it pointless to write it twice. So here comes the question. How can I write a standard component, using props that I could pass, and have something like:

<MediaInput type='movies'/>
<MediaInput type='books'/>

instead of:

<MovieInput />
<BookInput />

The new component would probably look like:

class MediaInput extends React.Component {
  constructor(props) {
    super(props);
    firebase.initializeApp(config);
  
    this.state = {
          // Make use of some prop to set collection adequately ....
          // This what I don't know how to do ....
          collection: []
    };
  }

  ....
}

It may be useful to set the background of my question, to say that I got inspired by this tutorial to get started on writing the code above.

CodePudding user response:

I'm not familiar with firebase database.

But if I assume that

Firebase.database()
      .ref("/")
      .set(this.state);

Handle on his own the differents keys of your state (like all the CRUD behaviour on each values) this simple trick should work with your type props :

class MediaInput extends React.Component {
  constructor(props) {
    super(props);
    firebase.initializeApp(config);
  
    this.state = {
          // The array will have the key 'movies' or 'books'
          [props.type]: []
    };
  }

  ....
}

But take care to always have a 'type' prop defined !

CodePudding user response:

First, I would put the firebase details into a separate class to respect the SOLID Dependency Inversion Principle. For example:

class AppDatabase {
  constructor() {
    firebase.initializeApp(config);
  }

  addCollection(data) {
    return firebase.database().ref('/').set(data);
  }
}

Second, I would use the type prop as you do.

<MediaInput type='movies'/>
<MediaInput type='books'/>

Finally, use the AppDatabase in the components. For example

import { AppDatabase } from '../services';

class MediaInput extends React.Component {
  constructor(props) {
    super(props);
    this.appDatabase = new AppDatabase();
  
    this.state = {
      db: {
        [props.type]: []
      }
    };
  }

  addCollection() {
    this.appDatabase.addCollection(this.state.db);
  }
}
  • Related