Firebase、React 和 Redux 等待商店更新
Firebase, react and redux wait for store to update
我有一个连接到 Firebase 的 React 应用程序,我想检查用户是否在每次刷新页面时登录,调度 IS_SIGNED_IN
操作,这是操作创建者:
export function checkAuth() {
return dispatch => {
firebaseAuth().onAuthStateChanged((user) => {
if (user) {
dispatch(signedInAction())
} else {
dispatch(signedOutAction())
}
})
}
}
在 reducer 内部,我只是将布尔值 isAuthenticated
变为 true/false:
case ActionTypes.isSignedIn: {
return Object.assign({}, state, {
isAuthenticated: true
})
}
case ActionTypes.isSignedOut: {
return Object.assign({}, state, {
isAuthenticated: false
})
}
因为我想在应用程序加载时检查用户是否登录,所以我在 componentDidMount
发送操作(我猜这是错误的):
class Main extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
store.dispatch(checkAuth());
}
render() {
return (
<Provider store={store}>
<Router>
<Theme>
<Routes />
</Theme>
</Router>
</Provider>
);
}
}
这使得我检查 isAuthenticated
的代码失败,因为它尚未在商店中设置,例如在 Routes
组件中。解决这个问题的最佳方法是什么?总而言之,我知道我可以使用条件渲染并检查何时定义 isAuthenticated
,但我不喜欢该解决方案。想法?谢谢
我已经完成了您尝试对实时应用程序执行的操作,并在其中使用了 Firebase Auth。您需要使用 Actions 作为登录和注销,然后使用 componentWillMount() 和 componentWillReceiveProps() 检查用户是否登录:
操作:
import { auth } from '../fire';
export const GET_USER = 'get_user';
export function getUser(){
return dispatch => {
auth.onAuthStateChanged(user=>{
dispatch({
type: GET_USER,
payload: user
});
});
};
}
export function login(email,password){
return dispatch => auth.signInWithEmailAndPassword(email, password);
}
export function logout(){
return dispatch => auth.signOut();
}
export function createAccount(email, password){
return dispatch => auth.createUserWithEmailAndPassword(email, password);
}
你的 Reducer 应该有这个:
import {GET_USER} from '../Actions/UserActions';
export default function( state = {loading:true}, action){
switch (action.type){
case GET_USER:
return { loading: false, ...action.payload };
default:
return state;
}
}
例如,在您的 App.js 中,刚开始时使用:
componentWillMount(){
this.props.getUser();
if(this.props.user.loading === false && this.props.user.email === undefined){
this.props.history.replace('/Login');
}
}
componentWillReceiveProps(nextProps){
if(nextProps.user.loading === false && nextProps.user.email === undefined){
this.props.history.replace('/Login');
}
}
这是因为您的 props 中已经有了您的 Auth 凭据。
我希望这对你有用..
我有一个连接到 Firebase 的 React 应用程序,我想检查用户是否在每次刷新页面时登录,调度 IS_SIGNED_IN
操作,这是操作创建者:
export function checkAuth() {
return dispatch => {
firebaseAuth().onAuthStateChanged((user) => {
if (user) {
dispatch(signedInAction())
} else {
dispatch(signedOutAction())
}
})
}
}
在 reducer 内部,我只是将布尔值 isAuthenticated
变为 true/false:
case ActionTypes.isSignedIn: {
return Object.assign({}, state, {
isAuthenticated: true
})
}
case ActionTypes.isSignedOut: {
return Object.assign({}, state, {
isAuthenticated: false
})
}
因为我想在应用程序加载时检查用户是否登录,所以我在 componentDidMount
发送操作(我猜这是错误的):
class Main extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
store.dispatch(checkAuth());
}
render() {
return (
<Provider store={store}>
<Router>
<Theme>
<Routes />
</Theme>
</Router>
</Provider>
);
}
}
这使得我检查 isAuthenticated
的代码失败,因为它尚未在商店中设置,例如在 Routes
组件中。解决这个问题的最佳方法是什么?总而言之,我知道我可以使用条件渲染并检查何时定义 isAuthenticated
,但我不喜欢该解决方案。想法?谢谢
我已经完成了您尝试对实时应用程序执行的操作,并在其中使用了 Firebase Auth。您需要使用 Actions 作为登录和注销,然后使用 componentWillMount() 和 componentWillReceiveProps() 检查用户是否登录:
操作:
import { auth } from '../fire';
export const GET_USER = 'get_user';
export function getUser(){
return dispatch => {
auth.onAuthStateChanged(user=>{
dispatch({
type: GET_USER,
payload: user
});
});
};
}
export function login(email,password){
return dispatch => auth.signInWithEmailAndPassword(email, password);
}
export function logout(){
return dispatch => auth.signOut();
}
export function createAccount(email, password){
return dispatch => auth.createUserWithEmailAndPassword(email, password);
}
你的 Reducer 应该有这个:
import {GET_USER} from '../Actions/UserActions';
export default function( state = {loading:true}, action){
switch (action.type){
case GET_USER:
return { loading: false, ...action.payload };
default:
return state;
}
}
例如,在您的 App.js 中,刚开始时使用:
componentWillMount(){
this.props.getUser();
if(this.props.user.loading === false && this.props.user.email === undefined){
this.props.history.replace('/Login');
}
}
componentWillReceiveProps(nextProps){
if(nextProps.user.loading === false && nextProps.user.email === undefined){
this.props.history.replace('/Login');
}
}
这是因为您的 props 中已经有了您的 Auth 凭据。
我希望这对你有用..