90199


### 前提

現在ポートフォリオサイトを作成しています。  
<https://github.com/takoyan33/manga-kousatu.net>  
<https://mangakousatunet.vercel.app/>

### 実現したいこと

現在ポートフォリオで作成していおり、  
登録処理をコンポーネント化したいと考えています。  
<https://mangakousatunet.vercel.app/register>  
登録処理はFirebase authcationを利用しています。

### 発生している問題・エラーメッセージ

ですが、ファイルを２つに分けて、signup.jsを作り、コンポーネント化しようとしたのですが、  
上手くコンポーネント化されずに、クリックしても反応がない状態です。  
関数を他ファイルに書くのが初めてなので、どこがおかしいか分からない状態です。  
分かる方がいればよろしくお願いします。

[code]

    #register.js
    import { app } from "../firebaseConfig";
    import {
      getAuth,
      createUserWithEmailAndPassword,
      GoogleAuthProvider,
      signInWithPopup,
    } from "firebase/auth";
    import { useState, useEffect } from "react";
    import { useRouter } from "next/router";
    import { MuiNavbar } from "../layouts/components/MuiNavbar";
    import Button from "@mui/material/Button";
    import Box from "@mui/material/Box";
    import TextField from "@mui/material/TextField";
    import Head from "next/head";
    import Link from "next/link";
     import SignUp from "./api/auth/signup";
    
    export default function Register() {
      const auth = getAuth();
      const router = useRouter();
      const googleProvider = new GoogleAuthProvider();
      const [email, setEmail] = useState("");
      const [password, setPassword] = useState("");
    
    
      const SignUpWithGoogle = () => {
        signInWithPopup(auth, googleProvider).then((response: any) => {
          console.log(response.user);
          sessionStorage.setItem("Token", response.user.accessToken);
          router.push("/home");
        });
      };
    
      return (
        <div>
          <Head>
            <title>漫画考察.net/新規登録</title>
            <meta name="description" content="Generated by create next app" />
            <link rel="icon" href="/favicon.ico" />
          </Head>
    
          <MuiNavbar />
          <div className="max-w-7xl m-auto">
            <h2 className="m-5 my-12 text-center text-2xl font-semibold">
              新規登録
            </h2>
    
            <Box
              component="form"
              className="flex justify-center max-w-7xl "
              noValidate
              autoComplete="off"
            >
              <div>
                <label className="text-center my-4">メールアドレス*</label>
                <br></br>
                <TextField
                  id="outlined-basic"
                  label="sample@gmail.com"
                  className="m-auto w-80"
                  variant="outlined"
                  onChange={(event) => setEmail(event.target.value)}
                />
                <br></br>
                <br></br>
    
                <label className="text-center my-4">パスワード（8文字以上)*</label>
                <br></br>
                <TextField
                  id="outlined-basic"
                  label="Password"
                  type="password"
                  variant="outlined"
                  className="m-auto w-80"
                  onChange={(event) => setPassword(event.target.value)}
                />
                <br></br>
                <br></br>
    
                <label className="text-center my-4">
                  確認用パスワード（8文字以上)*
                </label>
                <br></br>
                <TextField
                  id="outlined-basic"
                  label="Password"
                  type="password"
                  variant="outlined"
                  className="m-auto w-80"
                  onChange={(event) => setPassword(event.target.value)}
                />
                <br></br>
                <br></br>
                <Button
                  variant="outlined"
                  onClick={SignUp}
                  className="m-auto w-80 my-8"
                >
                  新規登録
                </Button>
                <br></br>
                <br></br>
                <Button
                  variant="outlined"
                  onClick={SignUpWithGoogle}
                  className="m-auto w-80 "
                >
                  Googleで新規登録
                </Button>
                <br></br>
                <br></br>
                <Button variant="outlined" className="m-auto w-80 my-8">
                  <Link href="/login">ログインはこちら</Link>
                </Button>
              </div>
            </Box>
          </div>
        </div>
      );
    }
    
    
    
[/code]

[code]

    #signup.js
    
    import { app } from "../../../firebaseConfig";
    import { getAuth, createUserWithEmailAndPassword } from "firebase/auth";
    import { useState } from "react";
    import { useRouter } from "next/router";
    import React from "react";
    
    export const SignUp = () => {
      const auth = getAuth();
      const router = useRouter();
      const [email, setEmail] = useState("");
      const [password, setPassword] = useState("");
    
      createUserWithEmailAndPassword(auth, email, password)
        .then((response) => {
          sessionStorage.setItem("Token", response.user.accessToken);
          console.log(response.user.accessToken);
          router.push("/home");
        })
        .catch((err) => {
          alert("emailが既にあります");
        });
    
      return SignUp;
    };
    
    
    
[/code]

成功している処理

[code]

    #register.js
    import { app } from "../firebaseConfig";
    import {
      getAuth,
      createUserWithEmailAndPassword,
      GoogleAuthProvider,
      signInWithPopup,
    } from "firebase/auth";
    import { useState, useEffect } from "react";
    import { useRouter } from "next/router";
    import { MuiNavbar } from "../layouts/components/MuiNavbar";
    import Button from "@mui/material/Button";
    import Box from "@mui/material/Box";
    import TextField from "@mui/material/TextField";
    import Head from "next/head";
    import Link from "next/link";
    
    export default function Register() {
      const auth = getAuth();
      const router = useRouter();
      const googleProvider = new GoogleAuthProvider();
      const [email, setEmail] = useState("");
      const [password, setPassword] = useState("");
    
      const SignUp = () => {
        let checkSaveFlg = window.confirm("この内容で登録しても大丈夫ですか？");
    
        if (checkSaveFlg) {
          createUserWithEmailAndPassword(auth, email, password)
            .then((response: any) => {
              sessionStorage.setItem("Token", response.user.accessToken);
              console.log(response.user.accessToken);
              router.push("/home");
            })
            .catch((err) => {
              alert("emailが既にあります");
            });
        } else {
        }
      };
      const SignUpWithGoogle = () => {
        signInWithPopup(auth, googleProvider).then((response: any) => {
          console.log(response.user);
          sessionStorage.setItem("Token", response.user.accessToken);
          router.push("/home");
        });
      };
    
      return (
        <div>
          <Head>
            <title>漫画考察.net/新規登録</title>
            <meta name="description" content="Generated by create next app" />
            <link rel="icon" href="/favicon.ico" />
          </Head>
    
          <MuiNavbar />
          <div className="max-w-7xl m-auto">
            <h2 className="m-5 my-12 text-center text-2xl font-semibold">
              新規登録
            </h2>
    
            <Box
              component="form"
              className="flex justify-center max-w-7xl "
              noValidate
              autoComplete="off"
            >
              <div>
                <label className="text-center my-4">メールアドレス*</label>
                <br></br>
                <TextField
                  id="outlined-basic"
                  label="sample@gmail.com"
                  className="m-auto w-80"
                  variant="outlined"
                  onChange={(event) => setEmail(event.target.value)}
                />
                <br></br>
                <br></br>
    
                <label className="text-center my-4">パスワード（8文字以上)*</label>
                <br></br>
                <TextField
                  id="outlined-basic"
                  label="Password"
                  type="password"
                  variant="outlined"
                  className="m-auto w-80"
                  onChange={(event) => setPassword(event.target.value)}
                />
                <br></br>
                <br></br>
    
                <label className="text-center my-4">
                  確認用パスワード（8文字以上)*
                </label>
                <br></br>
                <TextField
                  id="outlined-basic"
                  label="Password"
                  type="password"
                  variant="outlined"
                  className="m-auto w-80"
                  onChange={(event) => setPassword(event.target.value)}
                />
                <br></br>
                <br></br>
                <Button
                  variant="outlined"
                  onClick={SignUp}
                  className="m-auto w-80 my-8"
                >
                  新規登録
                </Button>
                <br></br>
                <br></br>
                <Button
                  variant="outlined"
                  onClick={SignUpWithGoogle}
                  className="m-auto w-80 "
                >
                  Googleで新規登録
                </Button>
                <br></br>
                <br></br>
                <Button variant="outlined" className="m-auto w-80 my-8">
                  <Link href="/login">ログインはこちら</Link>
                </Button>
              </div>
            </Box>
          </div>
        </div>
      );
    }
    
    
[/code]


CC BY-SA 4.0
2022-07-23T14:44:47.780
90165
2022-07-26T06:23:36.990
52921
question
reactjs next.js
Reactの処理のコンポーネント化に失敗する


処理を外部化したいのかUIを外部化したいのかで方向性がかわりますが、UIの分離を行うという理解で回答します

componentsフォルダをpagesと同じ階層に作成する想定です  
`SingUp` をコンポーネント名にしているため、イベント処理の関数名をSignUpから `OnSignUp` に変更しています

[code]

    // components/SignUp.tsx
    export default function SignUp() {
      const [email, setEmail] = useState<string>("");
      const [password, setPassword] = useState<string>("");
    
      const onSignUp = () => {
      };
    
      const onSignUpWithGoogle = () => {
      }; 
    
      return (
        <>
            <h2 className="m-5 my-12 text-center text-2xl font-semibold">
                新規登録
            </h2>
            <Box
            component="form"
            className="flex justify-center max-w-7xl "
            noValidate
            autoComplete="off"
        >
            <!-- ログインUI省略 -->
            </Box>
        </>    
      )
    }
    
[/code]

[code]

    // pages/register.tsx
    import SignUp from "../components/SignUp";
    
    export default function Register() {
      // 省略
    
      return (
        <div>
          <Head>
            <title>漫画考察.net/新規登録</title>
            <meta name="description" content="Generated by create next app" />
            <link rel="icon" href="/favicon.ico" />
          </Head>
    
          <MuiNavbar />
          <div className="max-w-7xl m-auto">
            <!-- SignUpコンポーネントを使用 -->
            <SignUp />
          </div>
        </div>
      );
    }
    
[/code]

ファイルを分けてUI表示のみの回答例ですが、まずはコンポーネントを読み込んで表示を試してみてはいかがでしょうか


CC BY-SA 4.0
2022-07-26T06:23:36.990
90199
2022-07-26T06:23:36.990
298
90165
answer