Creating a React and Reactstrap Card Gallery (original) (raw)

For this tutorial, you will be utilizing React, npm, Node.js, Bootstrap, and Reactstrap. To keep all of the development environments static, I would advise everyone to use the same text editor like myself, Visual Studio Code, for this tutorial. If you are not familiar with React, I would recommend that you try this tutorial here first.

The purpose of this tutorial is to be able to familiarize oneself with React while creating a card game menu gallery.

Sill new to React? We recommend reviewing our articles on props and states to familiarize yourself with these concepts before jumping in!

Prerequisites:

If you don’t have Node.js installed, I would recommend you install it from the source. If you do not have npm, I would recommend installing it for the source as well.

Did you come across any errors in this tutorial? Please let us know by completing this form and we’ll look into it!

Python Blog Image - Creating a React and Reactstrap Card Gallery

Once you have Node.js setup and npm, you will be able to install the other libraries through the terminal within Visual Studio Code terminal. Before we get into that, let’s have you create a folder and name it CARDUI once you have that built click terminal and open up a new terminal.

Type:

npm init

The npm init command will initialize creating a package.json file.

It will take you through several questions. You can leave everything defaults except for the entry point being index.html. Once you run through everything it will ask you if this is okay, answer yes.

npminit - Creating a React and Reactstrap Card Gallery

Next run the following command, which will install the create-react-app:

npm install create-react-app

What is create-react-app?

Create-react-app lets you scaffold and quickly create React apps with no build configurations.

Run the following to create a new app, naming it cardui:

createra - Creating a React and Reactstrap Card Gallery

You will now need to change directories to cardui by typing the following in the terminal:

cd cardui/

Now we need to install two more libraries. Bootstrap and Reactstrap. Run the following commands in the terminal to install them.

npm install boostrap npm install reactstrap

Now Open up the cardui folder and then open up the index.js file in the src folder and then add the following line into the imports:

import 'bootstrap/dist/css/bootstrap.min.css';

This adds a link to the Bootstrap CSS.

Components:

Now besides App.js we will be creating and using three more components in this React app. In addition to these three components, you will be utilizing two non-component JavaScript files that will be used to populate data for the cards and set filters to organize them by type. One of two additional non-component JavaScript files will be in JavaScript object notation, and the other one will be an array. We will export both.

Let’s start by having you create a new folder in the src folder named components and creating three new JavaScript files in there, CardInfo.js, Filter.js, and MainMenu.js. Then make another folder in the src folder named non-components and create two JavaScript filed named cards.js and filters.js. One last folder that you need to create is the images. Create that folder in the public folder. We will be using eight different images for this example supplied from opengameart.org. They are all under the CC0 license and are created by beouliin.

Open up filters.js and type in the following into it:

export const FILTERS = [ 'Fire', 'Grass', 'Water', 'Mountains', 'Air', 'Rock', 'Heart' ];

The const FILTERS will hold the types our cards can be, and this will be the filter attribute we will use to filter our card gallery.

Next, open up cards.js and type in the following into it:

export const CARDS = [ { id: 0, name: "Red Monster", image: "images/id0.jpg", type: "Fire", attack: "5", damage: "5", description: "A monster from the volcanic region." }, { id: 1, name: "Pink Monster", image: "images/id1.jpg", type: "Heart", attack: "4", damage: "2", description: "A monster from the heart region." }, { id: 2, name: "Orange Monster", image: "images/id2.jpg", type: "Mountains", attack: "22", damage: "3", description: "A monster from the heart region." }, { id: 3, name: "Blue Monster", image: "images/id3.jpg", type: "Water", attack: "1", damage: "13", description: "A monster from the water region." }, { id: 4, name: "Green Monster", image: "images/id4.jpg", type: "Grass", attack: "3", damage: "1", description: "A monster from the grass region." }, { id: 5, name: "Winged Monster", image: "images/id5.jpg", type: "Air", attack: "12", damage: "2", description: "A monster from the cloud region." }, { id: 6, name: "Spiky Monster", image: "images/id6.jpg", type: "Rock", attack: "4", damage: "6", description: "A monster from the mountain region." }, { id: 7, name: "Plant Monster", image: "images/id7.jpg", type: "Grass", attack: "8", damage: "4", description: "A monster from the jungle region." } ];

This will be the detailed information for the eight different types of cards we have. It doesn’t matter what the information in any of the portions is. These, json const variable and list const variable, are just a generic example to show you how to use a json and list within a React application. You can change anything you want and fiddle around with it, but if you make any changes to type you should make those changes to the FILTERS list as well because that is where the check and balances come into play later on.

Let us create an App.css. We will set the background color of the body and set a class type and set its background color as well. Normally you would set a variable within a component and set the properties for those elements within it, but this works just fine as well. It depends on how much you need to style, per component.

body { background-color: lightcyan; }

.cardInfo { background-color: lightblue; }

Here is an overview of the structure and file structure below. The first image is an outline of how the components relate to each and the second image is the file structure in my personal workplace.

As you can tell from the image below, it is a representation of the parents and child components and how each prop will be passed to its parent component.

fs1 - Creating a React and Reactstrap Card Gallery

Below is a representation of my personal work space. You should all have the same structure of folders and files, up to this point, if you are following along.

fs2 - Creating a React and Reactstrap Card Gallery

Now inside your cardui folder, open up the src folder and open up App.js.

Replace the original Class App Extends Component code with the following:

class App extends Component { render() { return (

); } }

Here we are replacing the standard code that comes with creating react app in App.js with our own which will render MainMenu only, as MainMenu will house all the other components.

FILTER.JS COMPONENT:

Now let’s open up the Filter.js file. You will be importing react components, Bootstrap card, and button components and the filter attribute list. Type in the following imports into it:

import React, { Component } from "react"; import { Card, CardImg, ButtonGroup, Button } from "reactstrap"; import { FILTERS } from "../non-components/filters";

The Filter component will render the all the card images and the side navigational filter. You will create two constant variable, card and filterButtons. The const cards will be a property that filters through the MainMenu state called cards for a specific type and maps individual keys to each card at rendering. Keys will be assigned using Math.random().toString(36).slice(2). There is a multitude of issues with generating keys in such a manner, but it will suit us perfectly fine for the scope of this tutorial. You can read more about the complexities of stringifying floating point numbers here.

The class of col-2 and m-1 will create a column of two and a margin of 1.

For the constant variable filterButtons, we will map the attribute types FILTERS from filters.js into a variable and use the fat arrow function to return a button that will have a key which will be the attribute type with an onclick event handler which will run a MainMenu method called cardFilterSelect, which updates the cardFilter state.

We use a combination of Reactstrap and Bootstrap for the quick scaffolding of the front-end. We use the Bootstrap classes for the grid and flexbox class elements and Reactstrap for the button and button groups.

It should look like the following:

class Filter extends Component { render() { const card = this.props.cards .filter(({ type }) => { return !this.props.filter || type === this.props.filter; }) .map(card => { return ( <div key={Math.random() .toString(36) .slice(2)} className="col-2 m-1" > <Card onClick={() => this.props.cardSelect(card.id)}> ); }); const filterButtons = FILTERS.map(filterName => { return ( <Button key={filterName} onClick={() => this.props.cardFilterSelect(filterName)} > {filterName} ); });

return (
  <div className="container">
    <div className="row">
      <div className="col d-flex align-content-start flex-wrap">{card}</div>
      <div className="p-5 col-1">
        <ButtonGroup size="lg" vertical>
          <h6 style={{ color: "blue" }}>Card Attributes</h6>

          <Button onClick={() => this.props.cardFilterSelect(null)}>
            All
          </Button>
          {filterButtons}
        </ButtonGroup>
      </div>
    </div>
  </div>
);

} } export default Filter;

CARDINFO.JS COMPONENT:

Next open up CardInfo.js and import React and Reactstrap.

import React, { Component } from "react"; import { Card, CardImg } from "reactstrap";

The class CardInfo will extend Component and we will create two custom methods, then render the class out. The two methods that will be created are renderCard and renderInfo. Both will take a single parameter known as the card. RenderCard will return a card component with a card image and renderInfo will return a list of all the card information. We separate each item into a list item in an unordered list, assign headings and variables. Remember this component, CardInfo, will only render if it not null – which can be triggered by the Filter component.

class CardInfo extends Component { renderCard(card) { return ( ); }

renderInfo(card) { return (