{"id":18594908,"url":"https://github.com/sethbergman/react-sign-up","last_synced_at":"2026-04-15T16:01:52.044Z","repository":{"id":69157498,"uuid":"93534306","full_name":"sethbergman/react-sign-up","owner":"sethbergman","description":"React Sign Up Component","archived":false,"fork":false,"pushed_at":"2018-06-23T02:28:40.000Z","size":505,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-16T12:14:21.752Z","etag":null,"topics":["progressive-web-app","pushstate","react","service-worker","webcomponents"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sethbergman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-06-06T15:31:05.000Z","updated_at":"2018-06-23T02:31:58.000Z","dependencies_parsed_at":null,"dependency_job_id":"ac73c48f-9a92-498e-918d-5700cd4d3f57","html_url":"https://github.com/sethbergman/react-sign-up","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sethbergman/react-sign-up","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethbergman%2Freact-sign-up","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethbergman%2Freact-sign-up/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethbergman%2Freact-sign-up/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethbergman%2Freact-sign-up/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sethbergman","download_url":"https://codeload.github.com/sethbergman/react-sign-up/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethbergman%2Freact-sign-up/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31848664,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-15T15:24:51.572Z","status":"ssl_error","status_checked_at":"2026-04-15T15:24:39.138Z","response_time":63,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["progressive-web-app","pushstate","react","service-worker","webcomponents"],"created_at":"2024-11-07T01:17:35.494Z","updated_at":"2026-04-15T16:01:52.001Z","avatar_url":"https://github.com/sethbergman.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Overview\n\nThis 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:\n\n-   Using `state` and `props`\n-   CSS animations\n-   Event handling\n-   Native browser validation for forms\n\n## Mounting with `state`\n\nReact 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.\n\nAdditionally, a React component can define it's own state using a `state` property for handling stateful components, such as our form element today.\n\nUsing 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.\n\n## What is `state`?\n\n When we refer to a component's `state`, we mean a snapshot of the instance of the component on the page.\n\n In regular HTML (without React), when we have a text `\u003cinput /` box on a page, the _state_ of the `\u003cinput /` element is that the _value_ of the `\u003cinput /` component is a blank string (i.e. `\"\"`).\n When our user types into the `\u003cinput /` box, the `state` changes for the `\u003cinput /` box to set the value to the keystroke the user made.\n\n 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_.\n\nIn this particular instance we are going to use the component's `state` to show and hide the form on the page.\n\nLet'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.\n\nThe basic stateful `App` component looks like this:\n\n`{lang=javascript,crop-query=(.App)}\n\u0026lt;\u0026lt;[](src/App.js)`\n\nReact components have a method that is frequently used called `getInitialState`.\n\nReact 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.\n\nLet's tell React that the `App` component keeps a single item in it's local state, a boolean we will call `mounted`.\n\n`{lang=javascript,crop-query=(.App .getInitialState)}\n\u0026lt;\u0026lt;[](src/App.js)`\n\nReact 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](#references).\n\nOne 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:\n\n`{lang=javascript,crop-query=(.App .componentDidMount)}\n\u0026lt;\u0026lt;[](src/App.js)`\n\nThis 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`.\n\n`{lang=javascript,crop-query=window(.componentDidMount,1,1)}\n\u0026lt;\u0026lt;[](src/App.js)`\nAlthough a component's state is available via `this.state`, we should treat `this.state`as a readonly object and only ever change the state using the `setState` method available on a React component.\n\nThe `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`.\n\nWe 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.\n\n`{lang=javascript,crop-query=window(.App .render,2,6)}\n\u0026lt;\u0026lt;[](src/App.js)`\n\nThis 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.\n\n## The Form\n\nOur 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  `\u003cInput/` component that also uses `this.props`.\n\n### `this.props`\n\nIn addition to the `state` property, React components have another property called `props`.\n\nThe 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.\n\n 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_.\n\n 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:\n\nAnother 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:\n\n`{lang=javascript,crop-query=window(.App .render,4,4)}\n\u0026lt;\u0026lt;[](src/App.js)`\nThen, in our form itself, the onSubmit event handler is given the submit callback function we passed down as a prop:\n\n`{lang=javascript,crop-query=window(.Modal .render,3,5)}\n\u0026lt;\u0026lt;[](src/App.js)`\nThe function we define as `onSubmit` can then be called by the child `\u003cModal /` component when the user hits the submit button in the view. The actual code for the function is found in the parent component:\n\n`{lang=javascript,crop-query=(.App .handleSubmit)}\n\u0026lt;\u0026lt;[](src/App.js)`\nWhen the user clicks the submit button this event handler is called and the `mounted` variable gets set back to `false`.\n\nWe also have three `Input` components which we'll define next.\n\n### Building reusable inputs\n\nWe can define a reusable component, which can take in `props` that get passed down from the parent `\u003cform /` component. Three `props` we'll want to pass into the `\u003cInput /` component are:\n\n-   name\n-   type\n-   placeholder\n\nThese particular values are JavaScript strings, unlike the `onSubmit` event handler where we passed a function.\n\nThese 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.\n\n`{lang=javascript,crop-query=(.Input)}\n\u003c\u003c[](src/App.js)`\n\n### Native browser validation\n\nTwo 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.\n\n## Animating with `ReactCSSTransitionGroup`\n\nAnimations 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.\n\nAdding animations via CSS files aren't always straight-forward. To address this problem, React provides an addon library to ease with the difficulties: ReactCSSTransitionGroup.\n\n The `ReactCSSTransitionGroup` library is not included by default when using the create-react-app tool.\n 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:\n\n `npm install react-addons-css-transition-group`\n\nLet'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:\n\n`{lang=javascript,crop-query=(.App .render)}\n\u0026lt;\u0026lt;[](src/App.js)`\n\nWhen the `App` component is mounted, our  `child` variable is assigned our Modal component:\n\n`{lang=javascript,crop-query=window(.App .render,1,5)}\n\u0026lt;\u0026lt;[](src/App.js)`\n\nBy wrapping the modal in a `ReactCSSTransitionGroup` component, we get access to the animation effect whenever the modal is added and removed from the DOM.\n\nThe `ReactCSSTransitionGroup` must be available and mounted in the DOM for the animations to take effect.\n\nIf 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:\n\n`{lang=javascript,crop-query=window(.App .render,9,12)}\n\u0026lt;\u0026lt;[](src/App.js)`\n\nUsing 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).\n\nTo start the app \u0026 cd into the code and type:\n\n`npm install \u0026\u0026 npm start`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsethbergman%2Freact-sign-up","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsethbergman%2Freact-sign-up","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsethbergman%2Freact-sign-up/lists"}