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 凭据。

我希望这对你有用..