javascript - 如何使用 Firebase 和 TypeScript 构建 HOC 上下文?
问题描述
我在使用 Firebase 进行身份验证的 React 应用程序中使用 TypeScript。在使用 TypeScript 之前,我为 Firebase 部分使用了常规上下文,这很好。但是,现在我已经添加了 TypeScript,但我遇到了错误。
例如,这是我的 SignIn 组件(为简洁起见,省略了一些部分):
import React, { Component } from 'react';
import Firebase, { withFirebase } from '../Firebase';
const SignInForm = (firebase:Firebase) => {
onSubmit = event => {
... uses firebase to handle authentication ...
};
render() {
return (
<form onSubmit={handleSubmit}>
... sign in form ...
</form>
);
}
}
export default withFirebase(SignInForm);
在 ../Firebase 我有 index.js,其中包含:
import FirebaseContext, { withFirebase } from './context';
import Firebase from './firebase';
export default Firebase;
export { FirebaseContext, withFirebase };
./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;
和 ./context.js 是:
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();
我得到的错误是在我的 SignIn 组件的导出行中:export default withFirebase(SignInForm);
。SignInForm 带有下划线,错误消息为:
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
所以,据我所知,问题在于 withFirebase 期望接收一个组件,但接收的是一个 JSX 元素。有没有办法在传入之前将 JSX 转换为组件?还是有另一种方法来解决这个问题?
解决方案
你SignInForm
对它是什么感到非常困惑。它是一个函数而不是类组件,但它有一个render()
方法而不是一个return
语句。它不接受作为函数组件的正确参数。它应该接受一个 props 对象,而不是接受一个名为firebase
. 您需要修复SignInForm
成合法的函数组件或类组件。
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>
);
}
}
正如当前编写的那样,您的withFirebase
HOC 只能接受一个类组件。您可以通过替换为轻松解决此React.ClassComponent
问题React.ComponentType
。
推荐阅读
- python - 如何将参数传递给`scipy.integrate.solve_ivp`中的事件函数?
- dart - 图片被上传多次而不是一次
- unity3d - 如何使用运动控制器移动对象
- mongodb - 无法连接到 Mongo atlas spring boot
- wordpress - 需要通过网络共享分类法所有站点
- java - 我如何从 MainActivity 的弹出登录转到另一个活动
- javascript - 比较两个数组并相应地更改属性
- c - 在 C 中使用 ' vs " 会发生什么?
- python - 根据现有数据框的条件创建一个新的数据框
- jquery-select2 - 如何使用 AJAX 预加载 select2 插件?