And*_*son 5 javascript json handlebars.js reactjs react-hooks
我 stringified通过 lamda 服务器将我的状态作为变量从表单发送到 POST 请求,然后解析它并将其发送到 sendgrid,我在那里使用发送网格模板功能。这要求我将 json 格式化为这样,以便循环遍历一个特定部分(多个复选框),所有部分都应该具有相同的键但不同的值,由reason="Weight Loss"表单中的 a 设置。以下是最终 json 的形成方式。
{
"name" :"anders",
"message" : "winfsdafasfdsfsadfsadnipeg",
"package" : "silver",
"email" : "email@email.com",
"subject" : "fdsafas",
"data":{
"reasonArray":[
{
"reason":"weightLoss"
},
{
"reason":"Sport"
}
]
}
}
Run Code Online (Sandbox Code Playgroud)
然后我可以做一些魔术并循环检查复选框中选中的原因
<ol>
{{#each data.reasonArray}}
<li>{{this.reason}} </li>
{{/each}}
</ol>
Run Code Online (Sandbox Code Playgroud)
现在,如果我使用单个键值对离开状态并且没有该data部分,我就可以使用它了。这是我最初的工作状态。
const [formState, setFormState] = React.useState({
name: "",
package: `${data.datoCmsPricing.title}`,
email: "",
subject: "",
weightLoss:"",
strength:"",
sport:"",
message: "",
})
Run Code Online (Sandbox Code Playgroud)
然后,我发生了以下onChange事件,该事件将输入字段的名称设置为键,将值或检查状态设置为值。在这里看到的
const onChange = (e) => {
if (e.target.type === 'checkbox' && !e.target.checked) {
setFormState({...formState, [e.target.name]: e.target.checked});
} else {
setFormState({...formState, [e.target.name]: e.target.value });
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的表格
<form onSubmit={submitForm}>
{/* <input type="text" name="package" value={data.datoCmsPricing.title} /> */}
<label>
Name
<input
type="text"
name="name"
value={formState.name}
onChange={onChange}
/>
</label>
<label>
Email
<input
type="email"
name="email"
value={formState.email}
onChange={onChange}
/>
</label>
<label>
Subject
<input
type="text"
name="subject"
value={formState.subject}
onChange={onChange}
/>
</label>
<div>
<h3>Reasons for wanting to train</h3>
<label>
Weight Loss
<input
type="checkbox"
name="weightLoss"
checked={formState.weightLoss}
onChange={onChange}
/>
</label>
<label>
Strength
<input
type="checkbox"
name="strength"
checked={formState.strength}
onChange={onChange}
/>
</label>
<label>
Sport
<input
type="checkbox"
name="sport"
checked={formState.sport}
onChange={onChange}
/>
</label>
</div>
<label>
message
<textarea
name="message"
value={formState.message}
onChange={onChange}
/>
</label>
<button type="submit">Submit</button>
</form>
Run Code Online (Sandbox Code Playgroud)
然后我将它发送到我的 lamdba 函数
const response = await fetch("/.netlify/functions/sendmail", {
method: "POST",
body: JSON.stringify(formState),
})
Run Code Online (Sandbox Code Playgroud)
现在,在发送到 lamdbda 函数并被解析后,我的状态在 json 中看起来如下所示
{
name: 'Anders',
package: 'silver',
email: 'email@email.com',
subject: 'fdsafa',
weightLoss: 'on',
strength: 'on',
sport: 'on',
message: 'fdsafasf'
}
Run Code Online (Sandbox Code Playgroud)
现在我想让我的初始状态看起来像 sendgird 想要的格式,所以这就是我尝试的状态设置。
const [formState, setFormState] = React.useState({
name: "",
package: `${data.datoCmsPricing.title}`,
email: "",
subject: "",
weightLoss:"",
strength:"",
sport:"",
message: "",
data:{
reasonArray:[
{
reason:""
},
{
reason:""
}
]
}
})
Run Code Online (Sandbox Code Playgroud)
然后我尝试使用以下内容更新已检查值的 onChange 事件,我还更新了我的表单,以便它获取用户友好的名称。见下面这段代码
const onChange = (e) => {
if (e.target.type === 'checkbox' && !e.target.checked) {
setFormState({...formState, data:{ reasonArray:[ { reason:e.target.reason}, ]}});
}
...
}
Run Code Online (Sandbox Code Playgroud)
表格变更
...
<label>
Weight Loss
<input
type="checkbox"
name="weightLoss"
reason="weightLoss"
checked={formState.weightLoss}
onChange={onChange}
/>
</label>
<label>
Strength
<input
type="checkbox"
name="strength"
reason="strength"
checked={formState.strength}
onChange={onChange}
/>
</label>
<label>
Sport
<input
type="checkbox"
name="sport"
reason="sport"
checked={formState.sport}
onChange={onChange}
/>
</label>
...
Run Code Online (Sandbox Code Playgroud)
经过我的尝试,我在 Post 请求后得到的结果 Json 是这样的。它不更新数据部分。所以生成的 Json 格式正确,但没有附加原因。提前感谢您的帮助。
{
"name":"Anders",
"package":"Silver",
"email":"email@email.com",
"subject":"fdsaf",
"weightLoss":"on",
"strength":"on",
"sport":"on",
"message":"fdsafas",
"data":{
"reasonArray":[
{
"reason":""
},
{
"reason":""
}
]
}
}
Run Code Online (Sandbox Code Playgroud)
尝试拉比的回答
...
const prepareDataForApi = (formData) => {
const newFormData = Object.assign({}, formData); // optional if passed cloned copy of formData object or you can also use lodash cloneDeep
newFormData.data = {
reasonArray:[]
};
Object.keys(newFormData.reasons).forEach(key => {
if(newFormData.reasons[key]){
newFormData.data.reasonArray.push({reason: key})
}
});
delete newFormData.reasons;
return newFormData;
}
const submitForm = async (e) => {
e.preventDefault();
setForm(false);
// const newFormData = prepareDataForApi(formData);
const newFormData = prepareDataForApi(formState);
console.log(newFormData);
...
Run Code Online (Sandbox Code Playgroud)
小智 4
1.保持初始状态如下:
{
"name":"Anders",
"package":"Silver",
"email":"email@email.com",
"subject":"fdsaf",
"message":"fdsafas",
"reasons": {
"weightLoss": true,
"strength": true,
"sport": true,
}
}
Run Code Online (Sandbox Code Playgroud)
const onChange = (e) => {
if (e.target.type === 'checkbox') {
const changedReason = e.target.getAttribute('name');
setFormState({...formState, reasons:{...formState.reasons, [changedReason]: !formState.reasons[changedReason]}});
}
...
}
Run Code Online (Sandbox Code Playgroud)
onSubmit():
在调用 api 之前,调用转换器函数,它将转换
formState为 lambda 函数所需的 JSON 格式
const prepareDataForApi = (formData) => {
const newFormData = Object.assign({}, formData); // optional if passed cloned copy of formData object or you can also use lodash cloneDeep
newFormData.data = {
reasonArray:[]
};
Object.keys(newFormData.reasons).forEach(key => {
if(newFormData.reasons[key]){
newFormData.data.reasonArray.push({reason: key})
}
});
delete newFormData.reasons;
return newFormData;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
28489 次 |
| 最近记录: |