Coder Social home page Coder Social logo

react-sign-up's Introduction

Overview

This sign up form has a few different features that are unique to React. The sign up form itself is a modal that uses CSS animations and slides down when the page loads and slides up after the user logs in. We are going to learn about the following features for this sign up form:

  • Using state and props
  • CSS animations
  • Event handling
  • Native browser validation for forms

Mounting with state

React uses the concept of components which, conceptually are containers for our data and UI. Each component has several properties and methods that we will take advantage of in this post and for the rest of the series.

Additionally, a React component can define it's own state using a state property for handling stateful components, such as our form element today.

Using the state property allows us to manipulate a React component's view and data associated with the view to keep track of the local state of the component.

What is state?

When we refer to a component's state, we mean a snapshot of the instance of the component on the page.

In regular HTML (without React), when we have a text <input / box on a page, the state of the <input / element is that the value of the <input / component is a blank string (i.e. ""). When our user types into the <input / box, the state changes for the <input / box to set the value to the keystroke the user made.

React's components can define their own state which we'll use in today's post, and others in the future. When we use state in a React component the component is said to be stateful.

In this particular instance we are going to use the component's state to show and hide the form on the page.

Let's create the sign up form by first wrapping it in a parent App component. This way we can define some methods in this parent component that we can use to show or hide the sign up modal view.

The basic stateful App component looks like this:

{lang=javascript,crop-query=(.App)} &lt;&lt;[](src/App.js)

React components have a method that is frequently used called getInitialState.

React expects us to return a JavaScript object from this method that stores any sort of data we want to manipulate or display in the component.

Let's tell React that the App component keeps a single item in it's local state, a boolean we will call mounted.

{lang=javascript,crop-query=(.App .getInitialState)} &lt;&lt;[](src/App.js)

React components also have 'lifecycle hooks' where we can define custom functionality during the different phases of the component. These methods are executed at specific points in a component's lifecycle 1.

One of these hooks is the componentDidMount method is executed just after the component has been rendered to the page. In order to define functionality during the lifecycle, we need to define the method in the component:

{lang=javascript,crop-query=(.App .componentDidMount)} &lt;&lt;[](src/App.js)

This method is where we set our mounted state to true as now our form is inserted into the DOM and our component is prepared to show it. We change the state of our data using a component method setState.

{lang=javascript,crop-query=window(.componentDidMount,1,1)} &lt;&lt;[](src/App.js) Although a component's state is available via this.state, we should treat this.stateas a readonly object and only ever change the state using the setState method available on a React component.

The setState method sends the state object into a queue to be batched for DOM updates, so modifying or changing any portion of a component's state should only happen via setState.

We only want to show the modal if it is mounted, so we can include a conditional rendering statement in our component that renders the form if and only if the component has been mounted.

{lang=javascript,crop-query=window(.App .render,2,6)} &lt;&lt;[](src/App.js)

This conditional statement creates the child component if the App component has been rendered to the DOM. Our child component, Modal contains a form inside of it.

The Form

Our Modal component contains a form that looks familiar if you've built a form with HTML before. However, there are a few differences between this form and a typical HTML form. The form contains a props attribute as well as a custom <Input/ component that also uses this.props.

this.props

In addition to the state property, React components have another property called props.

The difference between state and props can be a little confusing at first. props are used to pass down data and event handlers from parent components to child components. state on the other hand is used to manipulate the current state of a component.

Notice that a child component does not pass any data back up to it's parent component. This means we can only ever pass data down the component tree. This pattern of data passing is called one-way databinding.

A child component can inform the parent component about an update it makes, but cannot change the data itself. We'll look at this process next:

Another aspect about the props attribute that can be a little confusing is passing down a function as a prop. When our Modal component is created, we pass down the App component's handleSubmit function as a prop:

{lang=javascript,crop-query=window(.App .render,4,4)} &lt;&lt;[](src/App.js) Then, in our form itself, the onSubmit event handler is given the submit callback function we passed down as a prop:

{lang=javascript,crop-query=window(.Modal .render,3,5)} &lt;&lt;[](src/App.js) The function we define as onSubmit can then be called by the child <Modal / component when the user hits the submit button in the view. The actual code for the function is found in the parent component:

{lang=javascript,crop-query=(.App .handleSubmit)} &lt;&lt;[](src/App.js) When the user clicks the submit button this event handler is called and the mounted variable gets set back to false.

We also have three Input components which we'll define next.

Building reusable inputs

We can define a reusable component, which can take in props that get passed down from the parent <form / component. Three props we'll want to pass into the <Input / component are:

  • name
  • type
  • placeholder

These particular values are JavaScript strings, unlike the onSubmit event handler where we passed a function.

These props allow us to create reuseable components since we just have to pass in the type of input (either text, email or password), the name we want to associate with the input element, and the placeholder to a normal input element.

{lang=javascript,crop-query=(.Input)} <<[](src/App.js)

Native browser validation

Two of the input types we are using with this form are slightly different than the normal text type: password and email. With these input types, the browser will automatically do some validation and render the inputs slightly differently than a normal text type. Using the email type will make the browser do some simple validation of the text, including checking for the @ symbol. Using the password type automatically masks the input.

Animating with ReactCSSTransitionGroup

Animations in React are not always as simple as just adding a few transitions and translations to our CSS files. Since React's algorithm works differently than other JavaScript libraries such as JQuery, React requires some DOM nodes to be removed/added to the DOM instead of manipulated.

Adding animations via CSS files aren't always straight-forward. To address this problem, React provides an addon library to ease with the difficulties: ReactCSSTransitionGroup.

The ReactCSSTransitionGroup library is not included by default when using the create-react-app tool. Although this library is included with the code for this post, to use it in your own projects, we'll need to install it using the npm package manager:

npm install react-addons-css-transition-group

Let's look at how to use ReactCSSTransitionGroup with our form. We'll use a few props on the ReactCSSTransitionGroup element which define the CSS transition name as well as a few props to define variables:

{lang=javascript,crop-query=(.App .render)} &lt;&lt;[](src/App.js)

When the App component is mounted, our child variable is assigned our Modal component:

{lang=javascript,crop-query=window(.App .render,1,5)} &lt;&lt;[](src/App.js)

By wrapping the modal in a ReactCSSTransitionGroup component, we get access to the animation effect whenever the modal is added and removed from the DOM.

The ReactCSSTransitionGroup must be available and mounted in the DOM for the animations to take effect.

If the ReactCSSTransitionGroup node is mounted at the same time as it's children, the animations will not work. The ReactCSSTransitionGroup has two properties that manage the durations of the animation when the modal enters/leaves the DOM:

{lang=javascript,crop-query=window(.App .render,9,12)} &lt;&lt;[](src/App.js)

Using ReactCSSTransitionGroup is great because our component code is declarative and the CSS manages the transitions in between our states of mounted and unmounted (e.g. we're not iterating over opacity and y position).

To start the app & cd into the code and type:

npm install && npm start

react-sign-up's People

Contributors

sethbergman avatar

Watchers

 avatar  avatar

react-sign-up's Issues

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on all branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because we are using your CI build statuses to figure out when to notify you about breaking changes.

Since we did not receive a CI status on the greenkeeper/initial branch, we assume that you still need to configure it.

If you have already set up a CI for this repository, you might need to check your configuration. Make sure it will run on all new branches. If you don’t want it to run on every branch, you can whitelist branches starting with greenkeeper/.

We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on all branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet. We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please delete the greenkeeper/initial branch in this repository, and then remove and re-add this repository to the Greenkeeper App’s white list on Github. You'll find this list on your repo or organization’s settings page, under Installed GitHub Apps.

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on all branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet. We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please delete the greenkeeper/initial branch in this repository, and then remove and re-add this repository to the Greenkeeper App’s white list on Github. You'll find this list on your repo or organization’s settings page, under Installed GitHub Apps.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.