View on GitHub

hcard-builder

This is a React web app to demonstrate a simple business card creating page. I demonstrate how to manage state, pass state between components without using Redux.

Table of Contents

Table of contents generated with markdown-toc

Introduction

hCard Builder

hCard is a simple, open format for publishing people, companies and organizations on the web.

This application is built in react.

Run the App

You can run the app from https://react-hcard-builder.herokuapp.com/

To run the app from your local computer, going to the project folder

1. npm install

   this will install all required modules
   
2. npm start

   This will run the app in the development mode.
   Open http://localhost:3000 to view it in the browser.

Main Features

Application Folder Structure

This application is created using create-react-app. Below is the Folder Structure

hcard-builder/

  README.md

  node_modules/

  package.json

  public/

    index.html

    favicon.ico

  src/

    App.css

    App.js

    App.test.js

    index.css

    index.js

    logo.svg

    css/

      style.css

    components/

      hcardform.js

      hcardpreview.js

      inputFileReader.js

Components Structure

On the top level, I have App.js.

Inside App.js, I have two components:

HcardForm and HCardPreview.

The code is like this:

  <div className="hCard">
    <HCardForm />
    <HCardPreview />
  </div>

Development Consideration

Whenever a value changes in HCardForm component, it need to pass the state to HCardPreview component, and update HcardPreview component accordingly.

We know that we can pass state to component as props, we also know that state can only be passed from parent to child.

So the challenge is, how to pass state between two siblings.

To achieve that, we need to:

1. Pass states from HcardForm to the parent component, which is App component.

I define state in App component first

  constructor(props) {
    super(props);
    this.state = {
      givenName: "",
      surname: "",
      email: "",
      phone: "",
      houseNumber: "",
      street: "",
      suburb: "",
      state: "",
      postcode: "",
      country: "",
      avatar: ""
    };
  }

I then pass the state to HCardForm component as props

    <HCardForm
      formValue={this.state}
    />

Whenever an input field value is changes, we need to chang state in App component. In Order to do that, we use callback function.

    // callback
    handleFormFieldChange(formValue) {
        this.setState(formValue);
    }
 
   <HCardForm
      formValue={this.state}
      onFormFieldChange={this.handleFormFieldChange}
    />

When there is a change in HCardForm, it calls this.props.onFormFieldChange props, and pass the updated value back to the parent (App component).

Below is the code on how to impment this in HCardForm component:

whenever there is a change on input, we call onChange={this.handleFormInputChange

        <input
          type="text"
          name="givenName"
          value={formValue.givenName}
          placeholder="Given Name"
          onChange={this.handleFormInputChange}
        />

I then handle the event:

        handleFormInputChange(event) {
            const target = event.target;
            const value = target.value;
            const name = target.name;

            this.setState(
              {
                [name]: value
              },
              /* use callback function, only call this funciton after setState is completed */
              function() {
                this.props.onFormFieldChange(this.state);
              }
            );
         }

Note the code

           this.setState(
              {
                [name]: value
              },
              /* use callback function, only call this funciton after setState is completed */
              function() {
                this.props.onFormFieldChange(this.state);
              }
            );

It will not work if you change the code to

             this.setState(
              {
                [name]: value
              });
         
             this.props.onFormFieldChange(this.state);

Why? …

2. Pass state from App componet to HCardPreview component

in App.js, pass this.state as props

    <HCardPreview formValue={this.state} />