Firebase, реагировать и редукса ждать обновления магазина
У меня есть приложение React, подключенное к Firebase, я хочу проверять, вошел ли пользователь в систему при каждом обновлении страницы, отправке IS_SIGNED_IN
действие, вот создатель действия:
export function checkAuth() {
return dispatch => {
firebaseAuth().onAuthStateChanged((user) => {
if (user) {
dispatch(signedInAction())
} else {
dispatch(signedOutAction())
}
})
}
}
Внутри редуктора я просто делаю логическое isAuthenticated
в истину / ложь:
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
определяется, но мне не нравится это решение. Мысли? Спасибо
1 ответ
Я сделал то, что вы пытаетесь сделать с живым приложением, и использовал в нем Firebase Auth. Вам нужно использовать Действия в качестве входа в систему и только тогда выйти из системы, а затем с помощью 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);
}
ваш редуктор должен иметь это:
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');
}
}
это потому, что у вас уже есть учетные данные Auth в ваших реквизитах.
Я надеюсь, что это работает для вас..