Javascript 如何使用Firebase和TypeScript构建一个HOC上下文?

Javascript 如何使用Firebase和TypeScript构建一个HOC上下文?,javascript,reactjs,typescript,firebase,Javascript,Reactjs,Typescript,Firebase,我在React应用程序中使用TypeScript,该应用程序使用Firebase进行身份验证。在使用TypeScript之前,我对Firebase部分使用了常规上下文,这很好。然而,现在我已经添加了TypeScript,我得到了错误 例如,这里是我的SignIn组件(为简洁起见,省略了一些部分): /firebase.js是: import app from 'firebase/app'; import 'firebase/auth'; class Firebase { construc

我在React应用程序中使用TypeScript,该应用程序使用Firebase进行身份验证。在使用TypeScript之前,我对Firebase部分使用了常规上下文,这很好。然而,现在我已经添加了TypeScript,我得到了错误

例如,这里是我的SignIn组件(为简洁起见,省略了一些部分):

/firebase.js是:

import app from 'firebase/app';
import 'firebase/auth';

class Firebase {

  constructor() {
    app.initializeApp(config);
  }

  getUserIdToken = () => {
    if (app.auth().currentUser !== null) {
      return app.auth().currentUser?.getIdToken() as Promise<string>;
    }
    return Promise.reject("User not signed in") as Promise<string>;
  };

  ... various other firebase functions ...

}
 
export default Firebase;
将鼠标悬停在带下划线的错误上,可以得到函数定义:

const SignInForm: (firebase: Firebase) => JSX.Element

所以,从我所知道的,问题是withFirebase期望接收一个组件,但却接收一个JSX元素。在传入JSX之前,是否有方法将其转换为组件?还是有其他方法来解决这个问题?

您的
SignInfo
对它是什么感到非常困惑。它是一个函数而不是类组件,但它有一个
render()
方法,而不是
return
语句。它不接受作为函数组件的正确参数。它应该接受一个props对象,而不是一个名为
firebase
的参数。您需要将
signinfo
修复为合法的函数组件或类组件

const SignInForm: React.FC<{firebase:Firebase}> = ({firebase}) => {
    /* ... */
    return (
      <form onSubmit={handleSubmit}>
       ... sign in form ...
      </form>
    );
}
const signinfo:React.FC=({firebase})=>{
/* ... */
返回(
…登录表单。。。
);
}
类符号信息扩展了React.Component{
/* ... */
render(){
返回(
…登录表单。。。
);
}
}

正如当前编写的那样,您的
withFirebase
HOC只能接受类组件。您可以通过将
React.ClassComponent
替换为
React.ComponentType

轻松解决此问题。您已将您的
与Firebase
的参数定义为
ComponentClass
,而
signinfo
不是,或者是?看来已经很好了,谢谢!是的,我已经经历了这么多版本,这已经变得混乱。我要解开它!谢谢你,成功了。我只是在火炉底座周围加了一个花括号,它就把它修好了。
import React    from 'react';
import Firebase from './firebase';

const FirebaseContext = React.createContext<Firebase | null>(null);

export const withFirebase = (Component: React.ComponentClass) => (props:any) => (
  <FirebaseContext.Consumer>
    {
      firebase => <Component {...props} firebase={firebase} />
    }
  </FirebaseContext.Consumer>
)

export default FirebaseContext;
import React    from 'react';
import ReactDOM from 'react-dom';

import Firebase, { FirebaseContext }  from './components/Firebase';
import App                            from './components/App';

ReactDOM.render(
  <FirebaseContext.Provider value={new Firebase()}>
    <App />
  </FirebaseContext.Provider>,
  document.getElementById('root')
);

serviceWorker.unregister();
Argument of type '(firebase: Firebase) => JSX.Element' is not assignable to parameter of type 'ComponentClass<{}, any>'.
  Type '(firebase: Firebase) => Element' provides no match for the signature 'new (props: {}, context?: any): Component<{}, any, any>'.
const SignInForm: (firebase: Firebase) => JSX.Element
const SignInForm: React.FC<{firebase:Firebase}> = ({firebase}) => {
    /* ... */
    return (
      <form onSubmit={handleSubmit}>
       ... sign in form ...
      </form>
    );
}
class SignInForm extends React.Component<{ firebase: Firebase }> {
    /* ... */
    render() {
        return (
            <form onSubmit={handleSubmit}>
                ... sign in form ...
            </form>
        );
    }
}