Bookmarks MERN

Building A Simple Full Crud MERN App
Bookmarks MERN

Form Handling

There are two ways to handle forms in React.

  • Controlled Forms: The value of the inputs are bound to state, so value of state and the value of the inputs are always in sync.

  • Uncontrolled Forms: The forms are not bound by state, instead their values are pulled using a ref when needed.

Example of a Controlled Form

Parts:

  • object holding form values as state
  • handleChange function that updates the state when we type into the form
  • handleSubmit function to handle form submission and do what you want with the data
import { useState } from "react"

export default function Form(props) {
  //State to hold the form data
  const [form, setForm] = useState({
    name: "",
    age: 0,
  })

  // handleChange function
  const handleChange = event => {
    // dynamically update the state using the event object
    // this function always looks the same
    setForm({ ...form, [event.target.name]: event.target.value })
  }

  const handleSubmit = event => {
    // prevent page refresh
    event.preventDefault()
    // do what you want with the form data
    console.log(form)
  }

  // The JSX for the form binding the functions and state to our inputs
  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={form.name}
        onChange={handleChange}
        name="name"
        placeholder="write name here"
      />
      <input
        type="number"
        value={form.age}
        onChange={handleChange}
        name="age"
        placeholder="write age here"
      />
      <input type="submit" value="Submit Form" />
    </form>
  )
}

Example of an Uncontrolled Form

  • a ref created for each input
  • handleSubmit for when form is submitted
import { useRef } from "react"

export default function Form(props) {
  // ref to get input values
  const nameInput = useRef(null)
  const ageInput = useRef(null)

  const handleSubmit = event => {
    // prevent page refresh
    event.preventDefault()
    // do what you want with the form data
    console.log({
      name: nameInput.current.value,
      age: ageInput.current.value,
    })
  }

  // The JSX for the form binding the functions and state to our inputs
  return (
    <form onSubmit={handleSubmit}>
      <input type="text" ref={nameInput} placeholder="write name here" />
      <input type="number" ref={ageInput} placeholder="write age here" />
      <input type="submit" value="Submit Form" />
    </form>
  )
}

Part 1 Making The API & Connecting it to a React App

URL HTTP Verb Action
/api/bookmarks/:id DELETE destroy bookmark
/api/bookmarks/:id PUT update bookmark
/api/bookmarks POST create bookmark
/api/users/login POST Login User
/api/users/ POST Sign Up User
/api/users/bookmarks GET Get Users Bookmarks

User

name
email
password
bookmarks ref of bookmarks

Bookmark

title
link

Steps

  1. Use Create React App to Build App
  2. Add .env, server.js, .env.example, Models, Controllers, Routes and Config Folders
  3. Add Mongoose, Morgan, Bcrypt and Jsonwebtoken
  4. Build Server and config/database
  5. Build Bookmark Model and User Model
  6. Build Controllers for Bookmark and User
  7. Build Router For Bookmarks and User
  8. Test Login, SignUp, CreateBookmark, ListBookmarksByUser, DeleteBookmark, UpdateBookmark

Github Code

Part 2 Using Components to Properly Separate Concerns

Steps

  1. Login, SignUp, CreateBookmark, ListBookmarksByUser, DeleteBookmark, UpdateBookmark Functionality
  2. Login/SignUp Page and functionality
  3. BookmarksPage
  4. CreateBookmark Component and use UseRef for form
  5. Verify created bookmarks get added to list
  6. BookmarkList Component
  7. When Bookmark gets clicked it opens up Bookmark in a new tab
  8. Bookmark Component
  9. Update & Delete Bookmark Functionality applied
  10. Delete Via Button
  11. Update Via Conditionally Rendering Input Field Adding New Text and pressing enter
{ showUpdateInput ?
  <input type='text' defaultValue={bookmark.title} onKeyPress={(e) => e.key === 'Enter' && updateBookmark(e, bookmark._id, setShowUpdateInput) }/>:
  <span onClick={() => setShowUpdateInput(true)}>{bookmark.title}</span>}

Part 3 Using CSS Modules to Properly Style Components

Steps

  1. Add Sass
  2. Style Login/SignUp Page
  3. Style Bookmark
  4. Style BookmarkList
  5. Create Universal Body Styling