我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

在本文中,苏南大叔模仿React@19官方的useActionState()钩子,生成了一个新的自定义钩子。使用上和官方的useActionState()差不多,暂时命名为useActionState2()。本文从加深useActionState()钩子的理解,为主要目的。本文的自定义useActionState2()钩子功能上和useActionState()类似。

苏南大叔:React19,一个自定义的表单提交钩子useActionState2 - 一个自定义的表单提交钩子useActionState2
React19,一个自定义的表单提交钩子useActionState2(图4-1)

苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。本文测试环境:nodejs@20.18.0create-react-app@5.0.1react@19.0.0

钩子定义

useActionState2.js:

import { useState } from "react";
function useActionState2(submitAction, initialState) {
  const [state, setState] = useState(initialState);
  const [isPending, setPending] = useState(false);
  const [result, setResult] = useState(null);
  const handleInputChange = (event) => {
    setState({
      ...state,
      [event.target.name]: event.target.value,
    });
  };
  const handleSubmit = async (event) => {
    event.preventDefault();
    setPending(true);
    setResult(null);
    try {
      setResult(await submitAction(state));
    } catch (error) {
      setResult({ error: error.message });
    } finally {
      setPending(false);
    }
  };
  return {
    result,
    state,
    handleInputChange,
    handleSubmit,
    isPending,
  };
}
export default useActionState2;

苏南大叔:React19,一个自定义的表单提交钩子useActionState2 - 钩子主体逻辑
React19,一个自定义的表单提交钩子useActionState2(图4-2)

使用范例

import React from "react";
import useActionState2 from "./useActionState2";
import axios from "axios";
const App = () => {
  const { result, state, handleInputChange, handleSubmit, isPending } =
    useActionState2(
      async (state) => {
        let response = await axios.post("/submit", state);
        return response.data;
      },
      { name: "", email: "" }
    );
  return (
    <>
      <style>{"input{width:100px}.red{color:red}"}</style>
      <form onSubmit={handleSubmit}>
        <input
          name="name"
          value={state.name}
          onChange={handleInputChange}
          placeholder="Name"
        />
        <input
          name="email"
          value={state.email}
          onChange={handleInputChange}
          placeholder="Email"
        />
        <button type="submit" disabled={isPending}>
          {isPending ? "Submitting..." : "Submit"}
        </button>
        {result && (
          <div>
            {result?.error && !isPending && (
              <span className="red">{result?.error}</span>
            )}
            {result?.message && !isPending && <span>{result?.message}</span>}
          </div>
        )}
      </form>
    </>
  );
};
export default App;

苏南大叔:React19,一个自定义的表单提交钩子useActionState2 - 可能的不同之处
React19,一个自定义的表单提交钩子useActionState2(图4-3)

配套后端express

var express = require("express");
var app = express();
let server = app.listen(3222, function () {
  let port = server.address().port;
  console.log(`访问地址为 http://localhost:${port}`);
});
const formidable = require("formidable");
app.post("*", (req, res) => {
  const form = new formidable.IncomingForm();
  form.parse(req, function (err, fields, files) {
    let name = fields["name"].toString().trim();
    if (name === "") {
      return res.json({ error: "用户名不能为空" });
    }
    let email = fields["email"].toString().trim();
    if (email === "") {
      return res.json({ error: "邮箱地址不能为空" });
    }
    res.json({ message: "ok," + name });
  });
});

苏南大叔:React19,一个自定义的表单提交钩子useActionState2 - 运行结果
React19,一个自定义的表单提交钩子useActionState2(图4-4)

package.json:

{
  //...
  "proxy": "http://localhost:3222/",
  //...
}

结语

更多苏南大叔的React经验文章,请参考下面的链接:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   react