React19,一个自定义的表单提交钩子useActionState2
发布于 作者:苏南大叔 来源:程序如此灵动~ 我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...
在本文中,苏南大叔模仿React@19
官方的useActionState()
钩子,生成了一个新的自定义钩子。使用上和官方的useActionState()
差不多,暂时命名为useActionState2()
。本文从加深useActionState()
钩子的理解,为主要目的。本文的自定义useActionState2()
钩子功能上和useActionState()
类似。
苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。本文测试环境:nodejs@20.18.0
,create-react-app@5.0.1
,react@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;
使用范例
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;
配套后端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 });
});
});
package.json
:
{
//...
"proxy": "http://localhost:3222/",
//...
}
结语
更多苏南大叔的React
经验文章,请参考下面的链接:
如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。