React Hooks and HTML Form

Using React Hooks makes the encapsulation of form filling logic easier. This article demonstrates the application of common HTML forms with Hooks.

React

Javascript

Web Development

HTML

React Hooks

Table of Contents

1. input Text Input Field

const App = () => {
  const [form, setForm] = useState({
    age: null,
    email: "",
  })

  const handleChange = event => {
    const { name, value } = event.target
    setForm(prevState => ({
      ...prevState,
      [name]: value,
    }))
  }

  return (
    <form>
      <label>
        Age
        <input
          type="number"
          name="age"
          value={form.age}
          onChange={handleChange}
        />
      </label>
      <label>
        Email
        <input
          type="email"
          name="email"
          value={form.email}
          onChange={handleChange}
        />
      </label>
    </form>
  )
}

2. radio Single Selector

const CATEGORY_OPTIONS = ["Anime", "Book", "Game", "Real", "Music"]

const App = () => {
  const [form, setForm] = useState({
    category: "",
  })

  const handleChange = event => {
    const { name, value } = event.target
    setForm(prevState => ({
      ...prevState,
      [name]: value,
    }))
  }

  const categoryOptions = CATEGORY_OPTIONS.map(elem => (
    <>
      <input
        type="radio"
        name="category"
        value={elem}
        checked={form.category === elem}
        onChange={handleChange}
      />
      {elem}
      <br />
    </>
  ))

  return (
    <>
      {categoryOptions}
      <button onClick={() => console.log(form)}>提交</button>
    </>
  )
}

3. select option Drop-down List

const SOURCE_OPTIONS = [
  { key: "acfun", name: "AcFun" },
  { key: "youtube", name: "Youtube" },
  { key: "netflix", name: "Netflix" },
]

const App = () => {
  const [form, setForm] = useState({
    source: "bilibili",
  })

  const handleChange = event => {
    const { name, value } = event.target
    setForm(prevState => ({
      ...prevState,
      [name]: value,
    }))
  }

  const sourceOptions = SOURCE_OPTIONS.map(elem => (
    <option value={elem.key}>{elem.name}</option>
  ))

  return (
    <>
      <select name="source" value={form.source} onChange={handleChange}>
        {sourceOptions}
      </select>
      <button onClick={() => console.log(form)}>Submit</button>
    </>
  )
}

4. checkbox Multi-Selectors

4.1 Using Array Index

const SOURCE_OPTIONS = [
  { key: "acfun", name: "AcFun" },
  { key: "youtube", name: "Youtube" },
  { key: "netflix", name: "Netflix" },
]

const App = () => {
  const [source, setSource] = useState(
    SOURCE_OPTIONS.map(elem => ({
      ...elem,
      checked: false, // init all item as not selected
    }))
  )

  const handleChange = indexToUpdate => {
    // copy the state and update by index
    const updatedState = [...source]
    updatedState[indexToUpdate].checked = !updatedState[indexToUpdate].checked

    setSource(updatedState)
  }

  const sourceOptions = source.map((elem, index) => (
    <label key={elem.key}>
      <input
        type="checkbox"
        name={elem.key}
        onChange={() => handleChange(index)}
        checked={source[index].checked}
      />
      {elem.name}
      <br />
    </label>
  ))
  return (
    <>
      {sourceOptions}
      <button onClick={() => console.log(source)}>Submit</button>
    </>
  )
}

4.2 Using Object with key

Object can directly update the specified key, so you don't need to use an index. However, if the data is an array of objects, it needs to be converted into an Object first.

When updating state, you can also directly copy each layer.

setSource(prevState => ({
  ...prevState,
  [name]: {
    ...prevState[name],
    checked: checked,
  },
}))
const SOURCE_OPTIONS = [
  { key: "acfun", name: "AcFun" },
  { key: "youtube", name: "Youtube" },
  { key: "netflix", name: "Netflix" },
]

const App = () => {
  // convert t Object and init each elem's checked with false
  const initSource = SOURCE_OPTIONS.reduce(
    (acc, elem) => ({ ...acc, [elem.key]: { ...elem, checked: false } }),
    {}
  )
  const [source, setSource] = useState(initSource)

  const handleChange = event => {
    const { name, checked } = event.target

    const updatedState = { ...source }
    updatedState[name].checked = checked
    setSource(updatedState)
  }

  const sourceOptions = Object.keys(source).map(elem => (
    <label key={elem}>
      <input
        type="checkbox"
        name={elem}
        onChange={handleChange}
        checked={source[elem].checked}
      />
      {source[elem].name}
      <br />
    </label>
  ))

  return (
    <>
      {sourceOptions}
      <button onClick={() => console.log(source)}>Submit</button>
    </>
  )
}