Javascript 问题:未处理的拒绝(TypeError):无法读取属性';注册';未定义的

Javascript 问题:未处理的拒绝(TypeError):无法读取属性';注册';未定义的,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我正在尝试从中实现useAuth钩子 useAuth.js // Hook (use-auth.js) import React, { useState, useEffect, useContext, createContext } from "react"; import axios from 'axios'; //Credentials const authContext = createContext(); // Provider component that wraps you

我正在尝试从中实现useAuth钩子

useAuth.js

// Hook (use-auth.js)

import React, { useState, useEffect, useContext, createContext } from "react";
import axios from 'axios';

//Credentials


const authContext = createContext();

// Provider component that wraps your app and makes auth object ...
// ... available to any child component that calls useAuth().
export function ProvideAuth({ children }) {
  const auth = useProvideAuth();
  return <authContext.Provider value={auth}>{children}</authContext.Provider>;
}

// Hook for child components to get the auth object ...
// ... and re-render when it changes.
export const useAuth = () => {
  return useContext(authContext);
};

// Provider hook that creates auth object and handles state
function useProvideAuth() {

  const [user, setUser] = useState(null);
  const API_URL = "http://localhost:1038";

  // Wrap any Firebase methods we want to use making sure ...
  // ... to save the user to state.
  const signin = (email, password) => {
    return firebase
      .auth()
      .signInWithEmailAndPassword(email, password)
      .then(response => {
        setUser(response.user);
        return response.user;
      });
  };

  const register = (username, email, password) => {
    return firebase
      .auth()
      .createUserWithEmailAndPassword(email, password)
      .then(response => {
        setUser(response.user);
        return response.user;
      });
  };

  const signup = async (data) => {
    const SIGNUP_ENDPOINT = `${API_URL}/wp-json/wp/v2/users/register`;
    let response = '';
    try {
        response = await axios({
            method: 'post',
            responseType: 'json',
            url: SIGNUP_ENDPOINT,
            data: data
          });
    } catch(e){
        console.log(e);
    }
    console.log(response);
  };

  const signout = () => {
    return firebase
      .auth()
      .signOut()
      .then(() => {
        setUser(false);
      });
  };

  const sendPasswordResetEmail = email => {
    return firebase
      .auth()
      .sendPasswordResetEmail(email)
      .then(() => {
        return true;
      });
  };

  const confirmPasswordReset = (code, password) => {
    return firebase
      .auth()
      .confirmPasswordReset(code, password)
      .then(() => {
        return true;
      });
  };

  // Return the user object and auth methods
  return {
    user,
    signin,
    signup,
    register,
    signout,
    sendPasswordResetEmail,
    confirmPasswordReset
  };
}
//钩子(使用auth.js)
从“React”导入React、{useState、useEffect、useContext、createContext};
从“axios”导入axios;
//证书
const authContext=createContext();
//提供程序组件,用于包装应用程序并使auth对象。。。
// ... 可用于调用useAuth()的任何子组件。
导出函数ProvideAuth({children}){
const auth=useProvideAuth();
返回
{errors.terms&&

您必须同意这些条款和条件

} 提交 取消 ) }
当表单提交并调用useAuth钩子时,我收到了错误

Unhandled Rejection (TypeError): Cannot read property 'signup' of undefined
onSubmit
./pages/register.js:15
  12 | // Get auth state and re-render anytime it changes
  13 | const auth = useAuth();
  14 | const { register, handleSubmit, watch, errors } = useForm();
> 15 | const onSubmit = data => { auth.signup(data) }
     | ^  16 | 
  17 | return (
  18 |  <Layout>
未处理的拒绝(TypeError):无法读取未定义的属性“signup”
提交
/页数/注册号:15
12 |//获取身份验证状态并在其更改时重新渲染
13 | const auth=useAuth();
14 | const{register,handleSubmit,watch,errors}=useForm();
>15 | const onSubmit=data=>{auth.signup(data)}
| ^  16 | 
17 |返回(
18 |  
你知道我哪里出错了吗?这个钩子本来是要和firebase一起使用的,但是我正在为wordpress修改它,所以现在只设置了注册功能

Layout.js

    import Head from 'next/head'
    import Link from 'next/link'
    import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
    import { faCoffee } from '@fortawesome/free-solid-svg-icons'
    import '../styles/styles.sass'
    import { ProvideAuth } from "../hooks/useAuth";

    export default ({ children }) => {

    const toggleStyles = (event) => {
    document.querySelector('#burger').classList.toggle('is-active')
    document.querySelector('#navbarmenu').classList.toggle('is-active')
     }

    return (
    <ProvideAuth>
    <div>
      <Head>
        <title>Quiz Client</title>
        <meta name="viewport" content="initial-scale=1.0, width=device- 
     width"/>
      </Head>
      <header>
        <nav className="navbar is-primary" role="navigation" aria- 
         label="main navigation">
          <div className="navbar-brand">
            <a className="navbar-item">
                    <FontAwesomeIcon icon={faCoffee} />
            </a>
            <a id="burger" onClick={toggleStyles} 
                role="button" className="navbar-burger burger" aria- 
       label="menu" aria-expanded="false" data-target="navbarmenu">
              <span aria-hidden="true"></span>
              <span aria-hidden="true"></span>
              <span aria-hidden="true"></span>
            </a>
          </div>
          <div id="navbarmenu" className="navbar-menu">
            <div className="navbar-start">
              <Link prefetch href="/">
                <a className="navbar-item">Home</a>
              </Link>
              <Link prefetch href="/elsewhere">
                <a className="navbar-item">Elsewhere</a>
              </Link>
            </div>

            <div className="navbar-end"> 
              <Link prefetch href="/login">
                <a className="navbar-item">Login</a>
              </Link>
              <Link prefetch href="/register">
                <a className="navbar-item">Register</a>
              </Link>           
            </div>
          </div>
        </nav>
      </header>
      {children}
      <footer className="footer">
        <div className="content has-text-centered">
          <span>I'm the footer</span>
        </div>
      </footer>
      </div>
      </ProvideAuth>
      )
      }
从“下一个/头部”导入头部
从“下一个/链接”导入链接
从“@fortawesome/react fontawesome”导入{FontAwesomeIcon}
从“@fortawesome/free solid svg icons”导入{faCoffee}
导入“../styles/styles.sass”
从“./hooks/useAuth”导入{ProvideAuth};
导出默认值({children})=>{
常量切换样式=(事件)=>{
document.querySelector(“#burger”).classList.toggle('is-active'))
document.querySelector('#navbarmenu').classList.toggle('is-active'))
}
返回(
测验客户端
登记
{儿童}
我是页脚
)
}

请原谅格式化您的
注册表
组件未被
ProviderAuth
提供程序包装。您只需稍微重新排列组件即可解决此问题

function RegisterForm(props) {

  // Get auth state and re-render anytime it changes
  const auth = useAuth();
  const { register, handleSubmit, watch, errors } = useForm();
  const onSubmit = data => { auth.signup(data) }

  return (
    <div className="container mt-sm p-md">
      {/* the rest of your form */}
    </div>
  )
}

export default function Register(props) {
  return (
    <Layout>
      <RegisterForm />
    </Layout>
  )
}
功能注册表执行(道具){
//获取身份验证状态并在其更改时重新渲染
const auth=useAuth();
常量{register,handleSubmit,watch,errors}=useForm();
const onSubmit=data=>{auth.signup(data)}
返回(
{/*表单的其余部分*/}
)
}
导出默认功能寄存器(props){
返回(
)
}

你在哪里渲染
ProvideAuth
?@azium我更新了postYes这是我第一次使用nextjsOh..我想我看到了你的问题..版面有AuthProvider,但你正试图
在上面使用auth
。把你的AuthProvider移到树的更高的位置,就像字面上的顶层一样?你的意思?谢谢azium.我明白了现在
function RegisterForm(props) {

  // Get auth state and re-render anytime it changes
  const auth = useAuth();
  const { register, handleSubmit, watch, errors } = useForm();
  const onSubmit = data => { auth.signup(data) }

  return (
    <div className="container mt-sm p-md">
      {/* the rest of your form */}
    </div>
  )
}

export default function Register(props) {
  return (
    <Layout>
      <RegisterForm />
    </Layout>
  )
}