ero*_*msr 3 javascript typescript reactjs react-hooks
我很难弄清楚这一点。我想创建一个钩子,调用它来使用 fetch 提交表单。
这就是我现在所拥有的。持有表单的组件:
const MyForm = (): ReactElement => {
const [status, data] = useSubmitForm('https://myurl-me/', someData);
return <>
<div className='Feedback-form'>
<div className='body'>
<form>
<input type='text' name='username' placeholder='name' required />
<input type='email' name='email' placeholder='email' required />
<button className='submit-feedback-button' type='button'>Send feedback</button>
</form>
</div>
</div>
</>
}
Run Code Online (Sandbox Code Playgroud)
自定义钩子:
import { useState, useEffect } from 'react';
const useSubmitForm = (url: string, data: URLSearchParams): [string, []] => {
const [status, setStatus] = useState<string>('idle');
const [responseData, setData] = useState<[]>([]);
useEffect(() => {
if (!url) return;
const fetchData = async () => {
setStatus('fetching');
const response = await fetch(url, {
method: 'POST',
headers: {
'Accept': 'text/html',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: data
});
const data = await response.json();
setData(data);
setStatus('fetched');
};
fetchData();
}, [url]);
return [status, responseData];
};
export default useSubmitForm;
Run Code Online (Sandbox Code Playgroud)
我的问题是我认为这个钩子会立即被调用。如何创建这个钩子并以这样的方式调用它:仅在提交表单并且我需要在请求正文中发送的所有数据都包含在内时才调用它?
您是对的,该效果在组件安装时运行一次,并且由于url是 true,因此它会跳过早期返回并调用fetchData.
如何创建这个钩子并以这样的方式调用它:仅在提交表单并且我需要在请求正文中发送的所有数据都包含在内时才调用它?
您还需要返回一个函数,以便组件调用并传递表单字段值。我认为你有几个基本选择。
useSubmitForm。onSubmit从 中返回一个处理程序useSubmitForm以附加到您的form元素。不过,处理程序onSubmit需要知道要从事件访问哪些字段onSubmit,因此将字段名称数组传递给挂钩(即“配置”)是有意义的。fetchData从钩子中解开该函数useEffect并向其添加表单字段数据参数。由于fetch和response.json()都可以抛出错误/拒绝,因此您应该在 try/catch 中包围此块。返回fetchData要调用的表单的自定义函数。
使用提交表单
const useSubmitForm = (
url: string,
data: URLSearchParams
): [function, string, []] => {
const [status, setStatus] = useState<string>("idle");
const [responseData, setData] = useState<[]>([]);
const fetchData = async (formData) => {
setStatus("fetching");
try {
const response = await fetch(url, {
method: "POST",
headers: {
Accept: "text/html",
"Content-Type": "application/x-www-form-urlencoded"
},
body: JSON.stringify(formData)
});
const data = await response.json();
setData(data);
setStatus("fetched");
} catch (err) {
setData(err);
setStatus("failed");
}
};
return [fetchData, status, responseData];
};
Run Code Online (Sandbox Code Playgroud)
我的表格
const MyForm = (): ReactElement => {
const [fields, setFields] = useState({ // <-- create field state
email: '',
username: '',
});
const [fetchData, status, data] = useSubmitForm(
"https://myurl-me/",
someData
);
useEffect(() => {
// handle successful/failed fetch status and data/error
}, [status, data]);
const changeHandler = (e) => {
const { name, value } = e.target;
setFields((fields) => ({
...fields,
[name]: value
}));
};
const submitHandler = (e) => {
e.preventDefault();
fetchData(fields); // <-- invoke hook fetchData function
};
return (
<div className="Feedback-form">
<div className="body">
<form onSubmit={submitHandler}> // <-- attach submit handler
<input
type="text"
name="username"
placeholder="name"
onChange={changeHandler} // <-- attach change handler
value={fields.username} // <-- pass state
/>
<input
type="email"
name="email"
placeholder="email"
onChange={changeHandler} // <-- attach change handler
value={fields.email} // <-- attach state
/>
<button className="submit-feedback-button" type="submit">
Send feedback
</button>
</form>
</div>
</div>
);
};
Run Code Online (Sandbox Code Playgroud)
onSubmit处理程序并将一组字段传递给useSubmitForm使用提交表单
const useSubmitForm = (
url: string,
data: URLSearchParams,
fields: string[],
): [function, string, []] => {
const [status, setStatus] = useState<string>("idle");
const [responseData, setData] = useState<[]>([]);
const fetchData = async (formData) => {
setStatus("fetching");
try {
const response = await fetch(url, {
method: "POST",
headers: {
Accept: "text/html",
"Content-Type": "application/x-www-form-urlencoded"
},
body: JSON.stringify(formData)
});
const data = await response.json();
setData(data);
setStatus("fetched");
} catch (err) {
setData(err);
setStatus("failed");
}
};
const onSubmit = e => {
e.preventDefault();
const formData = fields.reduce((formData, field) => ({
...formData,
[field]: e.target[field].value,
}), {});
fetchData(formData);
}
return [onSubmit, status, responseData];
};
Run Code Online (Sandbox Code Playgroud)
我的表格
const MyForm = (): ReactElement => {
const [onSubmit, status, data] = useSubmitForm(
"https://myurl-me/",
someData,
['email', 'username'] // <-- pass field array
);
useEffect(() => {
// handle successful/failed fetch status and data/error
}, [status, data]);
return (
<div className="Feedback-form">
<div className="body">
<form onSubmit={onSubmit}> // <-- attach submit handler
<input
type="text"
name="username"
placeholder="name"
/>
<input
type="email"
name="email"
placeholder="email"
/>
<button className="submit-feedback-button" type="submit">
Send feedback
</button>
</form>
</div>
</div>
);
};
Run Code Online (Sandbox Code Playgroud)
在我看来,第二种解决方案是更清洁的解决方案,并且需要更少的消耗组件来使用。
| 归档时间: |
|
| 查看次数: |
5308 次 |
| 最近记录: |