Skip to content
youhoc
  • Pages
    • Home
    • Modern App Guidelines
    • Linux
      • Day 1: Linux Distributions & Navigation
      • Day 2: User Management
      • Day 3: File Permission & Ownership
      • Day 4: Package Management
      • Day 5: Services Management
    • Javascript
      • JS The Weird Part
        • Execution Context
        • Types & Operators
        • Objects & Functions
        • Error Handling & Strict Mode
        • Typescript, ES6, Tra
      • Modern JS
        • JS in the Browser
        • Data Storage JSON
        • Modern JS
        • Advanced Objects & Methods
        • Webpack & Babel
        • Async
      • jQuery
        • In-depth Analysis of jQuery
      • React-ready JS
        • Arrow Function
        • Template Literals
        • Logical AND, OR, Ternary, Nullish Operators
        • Destructuring & Rest Operator
        • Array Method
        • Immutability and Spread Operator
        • Promises, Async/Await, Callback
    • PHP
      • gruntJS
      • composer
      • MySQL
    • Docker
      • Container Basics
      • Container Networking
      • Container Image
      • Container Volume & Persistent Data
      • Dockerfile
      • Docker Compose
      • Docker Registry
    • Node.js
      • 1. Installing & Exploring
      • 2. Core Modules
      • 3. Get User Input
      • File System & Input Arguments
      • 5. Express Web Server
      • 6. Deploy to Heroku & Github
      • Authentication
      • 7. Databases
      • 8. Rest API
    • ReactJS
      • React from Andrew
        • Summary from Next
        • 1. Basics
        • 2. React Components
        • 3. Webpack
        • 4. Styling with SCSS
        • 5. React Router
        • 6. React Hook
      • Modern React From The Beginning
        • Intro to JSX
        • Vite Build Tools
        • Basic Component Creation
        • Component State
        • Props & Component Composition
        • icon picker
          useState with Inputs & Form Submission
        • useEffect, useRef & Local Storage
        • Async / Await and Http Request in React
        • React Router: Declarative Mode
        • ContextAPI
        • React Router: Framework Mode
          • File-routing & HTML Layouts
          • Server-side Data Query
          • Links & Navigation
          • Loaders
    • Typescript
      • Type User vs UserProp
    • Payload CMS

useState with Inputs & Form Submission

Controlled & Uncontrolled Inputs

Controlled input

When you add value={formData.title} , the input’s value is always tied to React state.
Whatever you type → triggers onChange → updates state → React re-renders input with new value.
React is the single source of truth.
Example:
If you do not have onChange handler, you will run into a warning:
We made this a controlled component by setting the `value` prop to the `title` state. But with a controlled component, you need to make sure that you upate that state whenever you type into the input.

Uncontrolled input

When you don’t add value={...} , the browser itself manages the input’s internal value.
You can still type text, submit forms, and even read the value later (e.g. e.target.value in onChange ).
React does not directly control what’s inside the box — it only reacts when you ask (via events or refs).
Your code:
This is an uncontrolled input.
The browser shows what you type.
Each keystroke triggers handleChange, where you probably do something like setFormData({ ...formData, [e.target.name]: e.target.value }).
So React still knows the value (in state), but the UI itself isn’t locked to state.

Why can you still submit and save?

Because the form submission uses the current DOM input value (e.target.value ) or your state that gets updated inside onChange . Both ways work:
If you read directly from state → your handleChange has been updating it.
If you read directly from the <input> element on submit → the browser kept track of the typed value.

formData or separate form elements

Collecting separate form elements
You should see the form with all the fields.
We have our inputs as their own state, however, you may be creating a form with many fields. You could create a single state object to hold all the form values. This way, you only need to update one state object instead of multiple states. We will look at that next.

Props Drilling

Truyền Props sẽ bắt đầu phức tạp khi mà:
có nhiều hơn 2-3 lớp components
có nhiều props cần phải truyền lên hoặc xuống
deleteNotes truyền từ App → NoteList → Note để gọi
setNotes truyền từ App → NoteForm để cập nhật state trong handleSave
handleChangehandleSave xử lý form trong NoteForm rồi cập nhật notes ở trên
Okay, so we have our notes app, but the notes are not persisting. If we refresh the page, the notes are gone. We need to save the notes to local storage so they persist. To do this, we can use the localstorage API along with a hook called `useEffect`.

Form Submit

Sau khi submit form, notes sẽ thay đổi state, dẫn đến việc cập nhật UI.
Đó là lý do cần khai báo notessetNotes ở App.jsx, rồi sau đó truyền xuống cho NoteForm.jsx xử lý, mutate notes.
We don't simply do notes.push(newNote) because we want to keep the notes state immutable.
SO we are using the spread operator to create a new array with the new note at the top.
If you wanted the new note at the bottom, you could do setNotes([...notes, newNote]) .

Collapsible Form

Conditional inline Styling

Delete Notes & Mutating Objects with filter()

Cách 1: Truyền thẳng một giá trị mới như thầy

Ở đây, notes chính là biến state hiện tại (giống như bạn đọc notes trực tiếp từ useState).
Bạn tính ra một array mới bằng filter, rồi React set state thành array đó.
Có thể gặp bug nếu nhiều setNotes chạy liên tiếp trong cùng một render cycle, vì notes lúc đó có thể đã “cũ”.
Cả 2 lần đều dùng chung cái notes ban đầu, nên cuối cùng chỉ xóa được 1 cái, chứ không phải cả 2.

Cách 2: Truyền một callback function

Ở đây, bạn không truyền giá trị, mà truyền một hàm.
React sẽ tự động gọi hàm này, và truyền giá trị state hiện tại (notes) vào tham số đầu tiên, ở đây là prevNotes.
Kết quả return từ hàm (prevNotes.filter(...)) sẽ được React dùng để cập nhật state mới.
Với cách này, React đảm bảo rằng nó luôn lấy state mới nhất để truyền vào callback.
React sẽ chắc chắn mỗi lần callback nhận prevNotes mới nhất, nên xóa được cả 2 như mong muốn.
Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.