'Custom hook build time problem - react typescript and next js
I am new to NextJS with ts and I have a build time problem. Please help me😥.
contact.tsx
You can see I fulfilled all recommendations (return type of hook, set into an array). But when I build code using this command (npm run build) shows me some errors like this -> (Objects are not valid as a React child (found: an object with keys {}). If you meant to render a collection of children, use an array instead.)
import React from "react";
import { NextPage } from "next";
import style from "../styles/contact.module.scss";
import useForm,{formDataType} from './hooks/useForm.hook';
//use react dangerouslySetInnerHTML
function createMarkup() {
return { __html: "Contact page" };
}
//Set data type(formDataType) and initial objects
const initialState: formDataType = {
name: "",
email: "",
phone: "",
textarea: "",
};
const Contact: NextPage = () => {
//Use our custom hook to handle form Data.
const [values, setValue, onChange, onSubmit]= useForm(sendDataToDataBase,initialState);
/* A submit function that will execute upon form submission
(send data to database or api or etc..)*/
async function sendDataToDataBase() {
//Set data to api -> using post method https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
fetch("http://localhost:3000/api/HandelPost", {
method: "POST", // or 'PUT'
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(values),
})
.then((response) => response.json())
.then(() => {
alert("Thank you for joining us");
setValue({ name: "", email: "", phone: "", textarea: "" });
})
.catch((error) => {
console.error("Error:", error);
});
}
return (
<div className={style.contact}>
{/* Render markup using -> dangerouslySetInnerHTML */}
<h1 dangerouslySetInnerHTML={createMarkup()}></h1>
<form onSubmit={onSubmit}>
<div className={style.contact_item}>
<label htmlFor="name">Enter your Name</label>
<input
type="text"
id="name"
aria-describedby="emailHelp"
name="name"
placeholder="Name"
onChange={onChange}
value={values.name}
required
/>
</div>
<div className={style.contact_item}>
<label htmlFor="email">Enter your Email address</label>
<input
type="email"
id="email"
aria-describedby="emailHelp"
name="email"
placeholder="Email"
onChange={onChange}
value={values.email}
required
/>
</div>
<div className={style.contact_item}>
<label htmlFor="phone">Enter your Phone number</label>
<input
type="tel"
id="phone"
aria-describedby="emailHelp"
name="phone"
placeholder="phone"
onChange={onChange}
value={values.phone}
required
/>
</div>
<div className={style.form_floating}>
<label htmlFor="floatingTextarea2">Elaborate concern</label>
<textarea
className="form-control"
placeholder="Leave a comment here"
id="floatingTextarea2"
name="textarea"
onChange={onChange}
value={values.textarea}
></textarea>
</div>
<button type="submit" className="btn btn-primary">
Submit
</button>
</form>
</div>
);
};
export default Contact;
Custome hook -> useForm.hook.ts
I think I have a problem with the return type Please view in ... Thank you in advance for your help.
import React from "react";
export type formDataType = {
name: string;
phone: string;
email: string;
textarea: string;
};
let useForm = (callback: any, initialState: formDataType): [formDataType, React.Dispatch<React.SetStateAction<formDataType>>, (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>)=>void, (event: React.FormEvent<HTMLFormElement>) => Promise<void>]=> {
const [values, setValue] = React.useState(initialState);
//When change input field //Set type of e: ... -> form event
/*React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
(B..e)-> use <textarea>element*/
const onChange = (
event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
) => {
setValue({ ...values, [event.target.name]: event.target.value });
};
//When user submit form Data
const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
await callback();
};
//Return all of data and function
return [values, setValue, onChange, onSubmit];
}
export default useForm;
My problem was solved using this method(App compile perfectly) but I am not sure whether this method is correct or not...
-> I can "export" user form data directly from my app.
Contact.tsx
import React from "react";
import { NextPage } from "next";
import style from "../styles/contact.module.scss";
import useForm,{formDataType,Data} from './hooks/useForm.hook';
//use react dangerouslySetInnerHTML
function createMarkup() {
return { __html: "Contact page" };
}
//Set data type(formDataType) and initial objects
const initialState: formDataType = {
name: "",
email: "",
phone: "",
textarea: "",
};
const Contact:NextPage= () => {
//Use our custom hook to handle form Data.
const [setValue, onChange, onSubmit]= useForm(sendDataToDataBase,initialState);
/* A submit function that will execute upon form submission
(send data to database or api or etc..)*/
async function sendDataToDataBase(){
//Set data to api -> using post method https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
fetch("http://localhost:3000/api/HandelPost", {
method: "POST", // or 'PUT'
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(Data),
})
.then((response) => response.json())
.then(() => {
alert("Thank you for joining us");
setValue({ name: "", email: "", phone: "", textarea: "" });
})
.catch((error) => {
console.error("Error:", error);
});
}
return (
<div className={style.contact}>
{/* Render markup using -> dangerouslySetInnerHTML */}
<h1 dangerouslySetInnerHTML={createMarkup()}></h1>
<form onSubmit={onSubmit}>
<div className={style.contact_item}>
<label htmlFor="name">Enter your Name</label>
<input
type="text"
id="name"
aria-describedby="emailHelp"
name="name"
placeholder="Name"
onChange={onChange}
value={Data.name}
required
/>
</div>
<div className={style.contact_item}>
<label htmlFor="email">Enter your Email address</label>
<input
type="email"
id="email"
aria-describedby="emailHelp"
name="email"
placeholder="Email"
onChange={onChange}
value={Data.email}
required
/>
</div>
<div className={style.contact_item}>
<label htmlFor="phone">Enter your Phone number</label>
<input
type="tel"
id="phone"
aria-describedby="emailHelp"
name="phone"
placeholder="phone"
onChange={onChange}
value={Data.phone}
required
/>
</div>
<div className={style.form_floating}>
<label htmlFor="floatingTextarea2">Elaborate concern</label>
<textarea
className="form-control"
placeholder="Leave a comment here"
id="floatingTextarea2"
name="textarea"
onChange={onChange}
value={Data.textarea}
></textarea>
</div>
<button type="submit" className="btn btn-primary">
Submit
</button>
</form>
</div>
);
};
export default Contact;
Custome hook -> useForm.hook.ts
import React from "react";
export type formDataType = {
name: string;
phone: string;
email: string;
textarea: string;
};
type HookReturnType = [
setValue:React.Dispatch<React.SetStateAction<formDataType>>,
onChange:(event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void,
onSubmit:(event: React.FormEvent<HTMLFormElement>) => Promise<void>
];
let Data:formDataType;
export default function useForm(callback: any,initialState:formDataType):HookReturnType {
const [values, setValue] = React.useState(initialState);
Data = values;
//When change input field //Set type of e: ... -> form event
/*React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
(B..e)-> use <textarea>element*/
const onChange = (
event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
) => {
setValue({ ...values, [event.target.name]: event.target.value });
};
//When user submit form Data
const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
await callback();
};
//Return all of data and function
return [setValue,onChange,onSubmit];
}
export {Data} //-> use this method to solve my compile time error
Please review my code and suggest whether this will be fine or not.😊
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
