简体   繁体   English

如何在反应中触发 onClick 事件的自定义挂钩

[英]How to trigger a custom hook on onClick event in react

I want to call a custom hook that will send a email on clicking a button.我想调用一个自定义钩子,它会在单击按钮时发送 email 。

customHook.ts

async function sendEmail(userName: string, userEmail: string, userPhone: string) {

  const mailToUser = {
    to: userEmail,
    subject: mail.subject,
    body: mail.body,
  };

  await fetch(`/api/sendEmail`, {
    method: `POST`,
    headers: { 'Content-Type': `application/json` },
    body: JSON.stringify(mailToUser),
  });
  
  console.log(mailToUser);
}

export default sendEmail;

This is the custom hook file that needs to be call to send the mail when the button is clicked这是单击按钮时需要调用以发送邮件的自定义挂钩文件

contact.tsx

import sendEmail from 'src'

export const Contact = (props:any) {
  const userName = `Name`;
  const userEmail = `email`;
  const userPhone = `333333333`;

  return (
    <button onClick={() => sendEmail(userName, userEmail, userPhone)}>Contact</button>
  )
}

The error that comes when I click the button is:单击按钮时出现的错误是:

**Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:**

You can't use the hook directly like error said, but in your case, this is normally a method, This is not a hook.您不能像错误所说的那样直接使用钩子,但是在您的情况下,这通常是一种方法,这不是钩子。

Basically hook can be useful if you are managing some sort of state/context inside it to manage your application workflow and data.如果您在其中管理某种state/context以管理您的应用程序工作流程和数据,基本上钩子会很有用。 But if you simply want to send email only then you dont need any kind of hook for that.但是,如果您只想发送 email ,那么您不需要任何钩子。 You can simply create a method and call that method.您可以简单地创建一个方法并调用该方法。

Like in here in example:就像这里的例子:

// app.js
const sendEmail = async (email, subject, body) => {
  const mailToUser = {
    to: email,
    subject: subject,
    body: body
  };
  await fetch(`/api/sendEmail`, {
    method: `POST`,
    headers: { "Content-Type": `application/json` },
    body: JSON.stringify(mailToUser)
  });
  console.log(mailToUser);
};

export default function App() {
  return (
    <div className="App">
      <button onClick={() => sendEmail("test@gmail.com", "subject", "body")}>
        Send Email
      </button>
    </div>
  );
}

But if you're trying to implement a hook, you can simply do like that:但是如果你想实现一个钩子,你可以简单地这样做:

// useEmail.js
const useEmail = () => {
  const sendEmail = async (email, subject, body) => {
    const mailToUser = {
      to: email,
      subject: subject,
      body: body
    };
    await fetch(`/api/sendEmail`, {
      method: `POST`,
      headers: { "Content-Type": `application/json` },
      body: JSON.stringify(mailToUser)
    });
    console.log(mailToUser);
  };

  return { sendEmail };
};

export default useEmail;

and in your component you can implement it:在您的组件中,您可以实现它:

// app.js
import useEmail from "./hook/sendEmail";

export default function App() {
  const { sendEmail } = useEmail();
  return (
    <div className="App">
      <button onClick={() => sendEmail("test@gmail.com", "subject", "body")}>
        Send Email
      </button>
    </div>
  );
}

Its seems customHook.ts is not actually a hook, Read Hooks rules at React hook Rules它似乎customHook.ts实际上不是一个钩子,在React hook Rules中阅读 Hooks 规则

It doesn't necessarily needs to be a custom hook in this case, but in case if you want to stick this with the approach, we can try to return a function from your customHook which invokes the API call.在这种情况下,它不一定需要是自定义钩子,但如果您想坚持这种方法,我们可以尝试从您的 customHook 返回 function 调用 API 调用。

May be this is how we can tackle this:可能这就是我们可以解决这个问题的方法:

useSendEmail.ts使用SendEmail.ts

    const useSendEmail = () => { 

        const sendEmail = async(userName: string, userEmail: string, userPhone: string) { 
             const mailToUser = {
                 to: email,
                 subject: subject,
                 body: body
             }; 

             try { 
                 await fetch(`/api/sendEmail`, {
                     method: `POST`,
                     headers: { 'Content-Type': `application/json` },
                     body: JSON.stringify(mailToUser),
                 });
             } catch (error) { 
                 // Include your error handling here. 
                 console.log(error);
             }
        } 

        return { sendEmail };
    
    }

Now, you can use it in your component in this way:现在,您可以通过这种方式在组件中使用它:

contact.tsx联系人.tsx

    import { useSendEmail } from './useSendEmail.ts';
    
    export const Contact = (props:any) {
       const { sendEmail } = useSendEmail(); // Receiving the function from hook here. 
       const userName = `Name`;
       const userEmail = `email`;
       const userPhone = `333333333`;
        
       const onClickHandler = () => {
          sendEmail(userName, userEmail, userPhone)
       }

       return (
           <button onClick={onClickHandler}>Contact</button>
       )
     }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM