'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