我对本教程中的以下代码(可在GitHub上获得(中的导出魔法感到困惑:
import React, { Component } from 'react';
import withFirebaseAuth from 'react-with-firebase-auth'
import firebase from 'firebase/app';
import 'firebase/auth';
import firebaseConfig from './firebaseConfig';
import logo from './logo.svg';
import './App.css';
const firebaseApp = firebase.initializeApp(firebaseConfig);
class App extends Component {
render() {
const {
user,
signOut,
signInWithGoogle,
} = this.props;
if (user) {
console.log(user.uid);
}
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
{
user
? <p>Hello, {user.displayName}</p>
: <p>Please sign in.</p>
}
{
user
? <button onClick={signOut}>Sign out</button>
: <button onClick={signInWithGoogle}>Sign in with Google</button>
}
</header>
</div>
);
}
}
const firebaseAppAuth = firebaseApp.auth();
const providers = {
googleProvider: new firebase.auth.GoogleAuthProvider(),
};
export default withFirebaseAuth({
providers,
firebaseAppAuth,
})(App);
我不明白(1(为什么App.props
有新成员,以及(2(为什么这些新成员在App.render()
开始时没有定义。更详细地说:
- 根据文档,我知道在
export
中对withFireBaseAuth()
的调用返回一个函数,当以App
作为参数进行调用时,该函数返回一个组件。然而,这是一个新的组成部分。那么,为什么props
会被添加到App
中呢 - 对
withFireBaseAuth()
的调用出现在App
的定义之后,那么为什么App.props.user
在App.render()
中使用时没有定义呢
- 根据文档,我知道导出中对withFireBaseAuth((的调用返回一个函数,当调用以App为参数,返回一个组件。然而,这是一个新的组成部分那么,道具是如何添加到应用程序中的呢
withFirebaseAuth
是一个高阶组件,它实际上只是一个专门的高阶函数,它消耗一个React组件,给它注入额外的行为(道具等(,并返回一个新的组件。
一个非常简单的HOC可能看起来像这样:
const withMyHOC = Component => props => (
<Component {...props} extraProp="extraProp" />
);
并使用const MyComponentWithExtraProp = withMyHOC(MyComponent);
。
这里的技巧是,HOC返回React组件,即它们接收props
,然后将它们向前传递(扩展运算符(到要修饰的组件。
HOC也可以被编写来接受额外的论点。
const withMyHOC = (arg1, arg2) => Component => props => {
useEffect(() => {
console.log('rendered', arg2);
});
return (
<Component {...props} extraProp="extraProp" arg={arg1} />
)
};
并使用CCD_ 15。
withFirebaseAuth
似乎采用配置参数,创建身份验证提供程序,并将user
、signOut
和signInWithGoogle
作为道具注入到正在装饰的组件中,例如App
。
- 对withFireBaseAuth((的调用出现在应用程序的定义之后,所以App.props.user在App.render((
记住,这些只是组件声明。App
组件在文件中声明,然后用withFirebaseAuth
进行装饰,然后默认导出。
export default withFirebaseAuth({
providers,
firebaseAppAuth,
})(App);
在其他地方,App
(实际上是装饰过的(默认由React导入和渲染。
import App from '../path/to/app';
ReactDOM.render(
<App />,
document.getElementById("root")
);
请注意,我们不需要传递任何道具,但user
、signOut
和signInWithGoogle
将由withFirebaseAuth
注入。