嗨,大家好
我是这个本地反应的新手,我正在努力让反应原生,反应路由器4和firebase auth工作。我要做的是检查用户是否已登录。如果他们已登录,则会显示“splash”组件,如果未登录,则会重定向到“/ login”界面。
我确实关注了react router 4 auth文档,但我无法让它工作。现在我想知道我在这里缺少什么,如果有人可以向我解释这一点,那么我理解为什么它不起作用。
这是我想要实现的流程:
我正在为我的项目使用create-react-native-app,这是我的文件。
app.js(根组件)
export default class App extends React.Component {
constructor() {
super();
this.state = {
isAuth: false,
email: "",
password: ""
};
}
onHandleLogin = (e, type) => {
const event = e.nativeEvent.text;
this.setState({ [type]: event });
};
onSubmitLogin = () => {
const email = this.state.email;
const password = this.state.password;
firebase
.auth()
.signInWithEmailAndPassword(email, password)
.catch(err => {
console.log("error:", err);
});
};
isLoggedIn = () => {
firebase.auth().onAuthStateChanged(user => {
if (user) {
this.setState({ isAuth: true });
return true;
} else {
this.setState({ isAuth: false });
return false;
}
});
};
componentDidMount() {
this.isLoggedIn();
}
render() {
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route
{...rest}
render={props =>
this.isLoggedIn() ? (
<Component {...props} />
) : (
<Redirect
to={{
pathname: "/login",
state: { from: props.location }
}}
/>
)
}
/>
);
return (
<NativeRouter>
<View style={styles.container}>
<Switch>
<Route
path="/login"
render={props => (
<Login
{...props}
submitFunc={this.onSubmitLogin}
login={this.onHandleLogin}
msg={this.state.isAuth}
/>
)}
/>
<Route path="/register" component={Register} />
<PrivateRoute path="/" component={Splash} />
</Switch>
</View>
</NativeRouter>
);
}
}
Splash.js
import Home from "./../Home/Home";
const Splash = () => {
return (
<View style={styles.container}>
<Route exact path="/" component={Home} />
</View>
);
};
Login.js
const Login = ({ login, submitFunc }) => {
return (
<KeyboardAwareScrollView
resetScrollToCoords={{ x: 0, y: 0 }}
contentContainerStyle={styles.formContainer}
>
<InputContainer style={styles.inputContainer}>
<Logo source={logo} />
<Input
inputStyle={styles.input2}
onChange={e => login(e, "email")}
placeholder="Email"
clearButtonMode="always"
containerStyle={styles.input}
leftIcon={
<Icon
containerStyle={styles.iconContainer}
name="at"
size={20}
type="font-awesome"
color="#b2b2b2"
/>
}
/>
<Input
inputStyle={styles.input2}
onChange={e => login(e, "password")}
placeholder="Password"
clearButtonMode="always"
containerStyle={styles.input}
secureTextEntry={true}
leftIcon={
<Icon
containerStyle={styles.iconContainer}
name="lock"
size={20}
type="font-awesome"
color="#b2b2b2"
/>
}
/>
<Button
title="Log in"
buttonStyle={styles.button}
titleStyle={styles.buttonTitle}
onPress={() => submitFunc()}
/>
<Button
title="Forgot your password?"
buttonStyle={styles.buttonLink}
titleStyle={styles.buttonLinkTitle}
/>
<ForgotContainer>
<Text style={styles.text}>Don't have an account? </Text>
<Link component={TouchableOpacity} to="/register">
<Text>Create one</Text>
</Link>
</ForgotContainer>
</InputContainer>
</KeyboardAwareScrollView>
);
};
我感谢所有帮助和解释,谢谢高级人员
答案 0 :(得分:1)
根据firebase documentation,onAuthStateChanged
添加一个侦听器/观察者并返回一个非null函数():观察者的取消订阅函数。。
onAuthStateChanged(nextOrObserver, error, completed) returns function()
查看代码,有两件事你做错了
PrivateRoute
组件重新初始化侦听器,该组件不执行任何操作。unsubscribing
反过来添加额外的开销
醇>
最佳方法是按照以下步骤进行:
componentDidMount() {
// Bind the variable to the instance of the class.
this.authFirebaseListener = firebase.auth().onAuthStateChanged((user) => {
this.setState({
loading: false, // For the loader maybe
user, // User Details
isAuth: true
});
});
}
componentWillUnmount() {
this.authFirebaseListener && this.authFirebaseListener() // Unlisten it by calling it as a function
}
并在PrivateRoute
组件中,使用this.state
const PrivateRoute = ({ component: Component, isAuth, ...rest }) => ( // Pass it as a prop where your component is injected
<Route
{...rest}
render={props =>
isAuth ? (
<Component {...props} />
) : (
<Redirect
to={{
pathname: "/login",
state: { from: props.location }
}}
/>
)
}
/>
);
和
<PrivateRoute path="/" isAuth={this.state.isAuth} component={Splash} />
答案 1 :(得分:0)
确定这是否有问题但是this.isLoggedIn没有调用函数
this.isLoggedIn()实际上正在调用一个函数
答案 2 :(得分:0)
您应该在App渲染功能中检查this.state.isAuth
而不是this.isLoggedIn()
。
this.isLoggedIn
没有返回任何内容,并且总是伪造的(未定义),因此您将始终转到重定向案例。