在 useContext React 中出现未定义的错误

时间:2021-05-26 21:58:17

标签: reactjs amazon-cognito

我使用 AWS Cognito 进行登录身份验证。我可以使用它,但现在我想对其应用会话。为此,我想存储用户名和密码,并将它们传递给所有需要身份验证的页面。我在读取 useContext 中的身份验证函数时遇到问题。

我的 createContext 和 Provider 函数在 Account.js 文件中:

import React, { createContext } from 'react';
import { CognitoUser, AuthenticationDetails } from 'amazon-cognito-identity-js';
import Pool from '../../UserPool';

const AccountContext = createContext();

const Account = (props) => {
 const authenticate = async (Username, Password) => {
  return await new Promise((resolve, reject) => {
  const user = new CognitoUser({ Username, Pool });

  const authDetails = new AuthenticationDetails({ Username, Password });

  user.authenticateUser(authDetails, {
    onSuccess: data => {
      console.log('onSuccess: ', data);
      resolve(data);
      // setIsLoggedIn(true);
    },
    onFailure: err => {
      console.error('onFailure: ', err);
      reject(err);
    },
    newPasswordRequired: function(userAttributes, requiredAttributes) {
      // User was signed up by an admin and must provide new
      // password and required attributes, if any, to complete
      // authentication.
      console.log('user attri', userAttributes, this);

      // the api doesn't accept this field back
      delete userAttributes.email_verified;

      // unsure about this field, but I don't send this back
      delete userAttributes.phone_number_verified;

      // Get these details and call
      user.completeNewPasswordChallenge(password, userAttributes, this);
      resolve(data);
    },
  });
});
};
return (
  <AccountContext.Provider value={{ authenticate }}>
    {props.children}
  </AccountContext.Provider>
);
};
export { Account, AccountContext };

我的主要 app.js 文件是:

import {Account} from './components/Login/Account'

return (
  <Account>
    <ErrorBoundary context="App">
      <Provider store={store}>
        <AppProvider config={this._appConfig}>
          <I18nextProvider i18n={i18n}>
            <Router basename={routerBasename}>
              <WhiteLabelingContext.Provider value={whiteLabeling}>              
                        <OHIFStandaloneViewer />                        
              </WhiteLabelingContext.Provider>
            </Router>
          </I18nextProvider>
        </AppProvider>
      </Provider>
    </ErrorBoundary>
    </Account>
  );
 }

我的消费者文件(LoginPage.js)是:

import React, { useState, useContext } from 'react';
import { AccountContext } from './Account';


const LoginPage = () => {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const { authenticate } = useContext(AccountContext);

  const onSubmit = e => {
     e.preventDefault();
     authenticate(username, password)
      .then(data => {
        console.log('logged in ', data);
      })
  .catch(err => {
    console.error('failed to login: ', err);
  });
 };

我得到的错误是:“无法读取未定义的属性‘身份验证’”

你能告诉我我哪里出错了吗? 或者有什么更好的方法吗?

提前致谢。

1 个答案:

答案 0 :(得分:0)

证据表明 LoginPage 未在上下文提供程序中呈现。如果是,对 useContext 的调用将返回您传递给提供程序的 { authenticate } 对象。相反,它返回 undefined,这是上下文的默认值,因为您没有在对 createContext 的调用中提供自己的默认值。

幸运的是,有一种简单的方法可以测试这种情况。在对 createContext 的调用中,传递一个如下所示的对象:

{
  authenticate() {
    return Promise.reject('I'm not inside a provider!');
  }
}

如果理论正确,您应该会在触发 onSubmit 时在控制台中看到失败日志。