Design+Code logo

Quick links

Suggested search

CodeSandbox link

You can find the full code for this tutorial at https://codesandbox.io/s/useinput-hook-q39hg.

Create the form

In order to use the useInput hook, we'll need to have a form. Let's create one.

// Form.js

import React from "react";

const Form = () => {
    return (
        <form>
            <input placeholder="Email" />
            <input placeholder="Password" type="password" />
            <button type="submit">Sign in</button>
        </form>
    );
};

export default Form;

Create a new file

Create a new file called useInput.js, where we'll put our custom useInput hook in. Start by importing the useState hook from the React library.

// useInput.js

import { useState } from "react";

Create the custom hook

Next, create the custom hook. Remember that a custom hook must always start with the use keyword. We'll name it useInput, then export it at the bottom of the file.

// useInput.js

const useInput = () => {

}

export default useInput

Inside of the function, we'll create a new state. We'll call it value. Since it's a hook, it can take any value, so we'll use this generic name. The initial value of the state will be passed as an argument to the function. Usually, we'll set it to an empty string when we'll use the hook. More on that later.

// useInput.js

const useInput = (initialValue) => {
    const [value, setValue] = useState(initialValue);
}

Next, we'll need to create the onChange event. So we'll create a handleChange function inside of the useInput.

const useInput = (initialValue) => {
    const [value, setValue] = useState(initialValue);

    const handleChange = (event) => {
        setValue(event.target.value);
    };
};

Finally, we'll return an object. This object will contain the value, as well as an onChange event, which will be the handleChange function we just defined.

const useInput = (initialValue) => {
    const [value, setValue] = useState(initialValue);

    const handleChange = (event) => {
        setValue(event.target.value);
    };

    return {
        value,
        onChange: handleChange
    };
};

Use the hook

To use the hook, we just need to import it at the top of our file in which there's a form.

// Form.js

import useInput from "./useInput"

Let's say our form contains two input fields: an email field and a password field. We'll then use this hook twice, once for the email and another one for the password field. Let's create a variable for each input, and assign it to the useInput hook. The initial value we will pass will be an empty string, because we don't want the input to be filled by default.

// Form.js

const email = useInput("")
const password = useInput("")

Since the input requires a value and an onChange event, we can just pass them from the email and password constants we defined.

<input placeholder="Email" value={email.value} onChange={email.onChange}/>
<input placeholder="Password" type="password" value={password.value} onChange={password.onChange}/>

We can also refactor it to simply spread the email and password constants to its specific input field. This way, everything returned from the useInput hook will be passed to the input. You can read more about the spread syntax here.

<input placeholder="Email" {...email} />
<input placeholder="Password" type="password" {...password}/>

Use the hook with onSubmit

When the user submits the form, you can easily access the values of each variable like so:

const submitForm = (event) => {
    event.preventDefault()
		console.log("email", email.value)
		console.log("password", email.password)
}

Call this function on submit of the form.

<form onSubmit={submitForm}>
    {/* Some code... */}
</form>

When releasing your app to the public, remember to remove the console logs in the submitForm() since it's a security flaw to print the user's email and password on the console.

Final code

Here is the final code for the useInput hook:

import { useState } from "react";

const useInput = (initialValue) => {
    const [value, setValue] = useState(initialValue);

    const handleChange = (event) => {
        setValue(event.target.value);
    };

    return {
        value,
        onChange: handleChange
    };
};

export default useInput;

Here is the final code for the Form, along with styling using styled-components:

import React from "react";
import styled from "styled-components";

import useInput from "./useInput";

const SignInForm = () => {
    const email = useInput("");
    const password = useInput("");

    const submitForm = (event) => {
        event.preventDefault();
        console.log("email", email.value);
        console.log("password", password.value);
    };

    return (
        <FormWrapper onSubmit={submitForm}>
            <Title>Sign in</Title>
            <Input placeholder="Email" {...email} />
            <Input placeholder="Password" type="password" {...password} />
            <Button type="submit">Sign in</Button>
        </FormWrapper>
    );
};

export default SignInForm;

const FormWrapper = styled.form`
    display: grid;
    justify-content: center;
    gap: 20px;
    padding-bottom: 50px;
`;

const Title = styled.h1`
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
    font-style: normal;
    font-weight: bold;
    font-size: 40px;
    line-height: 48px;
    color: #ffffff;
    text-align: center;
`;

const Input = styled.input`
    background: rgba(255, 255, 255, 0.2);
    border-radius: 30px;
    padding: 10px 20px;
    background-blend-mode: overlay;
    background: rgba(255, 255, 255, 0.2);
    box-shadow: 0px 20px 40px rgba(31, 47, 71, 0.25), 0px 1px 5px rgba(0, 0, 0, 0.1), inset 0 0 0 0.5px rgba(255, 255, 255, 0.4);
    border: 1px solid rgba(250, 250, 250, 0.4);

    :focus {
        outline: none;
    }
`;

const Button = styled.button`
    background: linear-gradient(91.4deg, #2fb8ff 0%, #9eecd9 100%);
    padding: 12px 0;
    width: 200px;
    border: none;
    border-radius: 30px;
    color: white;
    font-weight: bold;
    font-family: Segoe UI, sans-serif;
    cursor: pointer;
    :focus {
        outline: none;
    }
`;

Learn with videos and source files. Available to Pro subscribers only.

Purchase includes access to 50+ courses, 320+ premium tutorials, 300+ hours of videos, source files and certificates.

BACK TO

Toggle a state

READ NEXT

Gatsby and React

Templates and source code

Download source files

Download the videos and assets to refer and learn offline without interuption.

check

Design template

check

Source code for all sections

check

Video files, ePub and subtitles

Videos

ePub

Assets

Subtitles

1

Intro to React Hooks

An overview of React Hooks and the frameworks you can use to build your React application blazingly fast

3:39

2

Create your first React app

Create your first React project from the Terminal and save it on your local computer

4:23

3

React Component

Create your first JSX component using React

2:54

4

Styling in React

How to style your React components using inline styling, separate stylesheets or styled-components

5:06

5

Styles and Props

Render different styles depending on different properties passed to your component

2:22

6

Understanding Hooks

Learn about the basics of React Hooks, which introduced at React Conf 2018

3:21

7

useState Hook

Use the useState hook to manage local state in your React component

2:54

8

useEffect Hook

Manage with your component's lifecycle with the useEffect hook

3:41

9

useRef Hook

Learn about the useRef hook, which replaces the JavaScript getElementById way

3:00

10

Props

Learn about props in React to pass data from parent to child components

3:11

11

Conditional Rendering

Render different UIs depending on different conditions and states

4:21

12

Load Local Data

Load local JSON data into your React application

4:04

13

Fetch Data from an API

Learn the basics of asynchronous functions and promises by fetching data from an API using fetch, useEffect and useState

5:40

14

Toggle a state

Learn how to toggle a state from true to false and back again

4:05

15

useInput Hook

Create a hook to get the value and the onChange event of input fields

6:04

16

Gatsby and React

Create a static content-oriented website using React on Gatsby

6:44

17

NextJS and React

Create your first NextJS React application

5:24

18

React TypeScript Part 1

Learn how to create a React TypeScript application using the Create React App, Gatsby and NextJS methods

8:19

19

React TypeScript Part 2

Learn the basics of TypeScript and how to use TypeScript in a React component

7:35

20

useScrollPosition Hook

Create a custom hook to listen to the current window position of the user

4:26

21

useOnScreen hook

Create a custom hook to listen to when an element is visible on screen

8:08

22

useContext Hook

Manage global states throughout the entire application

8:32

23

Fragments

Group multiple children together with React Fragments

2:43

24

Lazy Loading

Lazy Load heavy components to improve performance

4:05

25

React Suspense

Wait for data with React Suspense and React.lazy

3:13

26

Environment Variables

Make environment variables secret with a .env file

4:43

27

Reach Router

Create a multiple-pages React application with Reach Router

5:31

28

URL Params

Create unique URL with URL Params

4:04

29

SEO and Metadata

Optimize a React application for search engines with React Helmet

6:47

30

Favicon

Add an icon to a React website

3:03

31

Dynamic Favicon

Change the favicon's fill color depending on the user's system appearance

2:14

32

PropTypes

Implement props type-checking with PropTypes

3:54

33

Custom PropTypes

Create a custom PropType using a validator function

3:58

34

useMemo Hook

Prevent unnecessary re-renders when the component stays the same

4:05

35

forwardRef Hook

Forward a ref to a child component

3:28

36

Handling Events

How to handle events in React

5:44

37

Spread attributes

Learn how to make use of the spread operator

3:35

38

useMousePosition Hook

Detect the user's mouse position on a bound element

4:55

39

useReducer with useContext Part 1

Create a reducer to be used in a context

7:33

40

useReducer with useContext Part 2

Incorporate useReducer with useContext

6:48

41

useReducer with useContext Part 3

Connect the context and reducer with the frontend

5:43

42

Netlify

Deploy to production using Netlify

5:08

43

Gatsby Cloud

Deploy to production using Gatsby Cloud

6:19

44

Gatsby Plugin Image

Use gatsby-plugin-image for automatic image resizing, formatting, and higher performance

8:11

45

useOnClickOutside Hook

Toggle a modal visibility with a useOnClickOutside hook

6:32

46

useWindowSize Hook

Create a hook to determine the width and height of the window

4:14

47

usePageBottom hook

Detect if the user scrolled to the bottom of the page

4:48

48

useLocalStorage Hook

Store an item in a browser's local storage

5:27

49

Three.js in React Part 1

Bring your website to life with beautiful 3D objects

17:33

50

Three.js in React Part 2

Bring your website to life with beautiful 3D objects

11:18