Navigator doesn't Re-render after redux state change in React Navigation 5 - redux

I'm using a stack navigator from react navigation v5 with redux. The stack navigator should render AuthScreen when isAuthenticated is false and render HomeScreen when isAuthenticated changes to true.
AppNav.js
import React, {useState, useEffect} from 'react';
import {NavigationContainer} from '#react-navigation/native';
import {createStackNavigator} from '#react-navigation/stack';
import { connect } from 'react-redux';
import AuthScreen from '../screens/AuthScreen';
import HomeScreen from '../screens/HomeScreen';
const Stack = createStackNavigator();
const AppNav = ({isAuthenticated}) => {
const [logged, setLogged] = useState(false)
useEffect(() => {
if(isAuthenticated) {
console.log(logged);
setLogged(true);
} else {
setLogged(false);
console.log(logged);
}
},[isAuthenticated])
return (
<NavigationContainer>
<Stack.Navigator>
{
!logged?
<Stack.Screen name='Auth' component={AuthScreen} options={{headerShown: false}} />
:<Stack.Screen name='Home' component={HomeScreen} options={{headerShown: false}} />
}
</Stack.Navigator>
</NavigationContainer>
);
}
const mapStateToProps = ({isAuthenticated}) => {
return {
isAuthenticated
};
}
export default connect(mapStateToProps, null)(AppNav)
userAction.js
import {LOGIN_WITH_FACEBOOK} from './types';
export const loginWithFacebook = () => async(dispatch) => {
dispatch( { type: LOGIN_WITH_FACEBOOK, payload: {isAuthenticated: true} } );
}
userReducer.js
import {LOGIN_WITH_FACEBOOK} from '../actions/types.js';
const INITIAL_STATE = {
isAuthenticated: false
};
const userReducer = (state=INITIAL_STATE, action) => {
switch(action.type){
case LOGIN_WITH_FACEBOOK:
return {...state, ...action.payload};
default:
return state;
}
}
export default userReducer
rootReducer.js
import {combineReducers} from 'redux';
import userReducer from './userReducer';
const rootReducer = combineReducers({
user: userReducer
})
export default rootReducer

Fixed it by accessing the key of userReducer which is state.user.
AppNav.js
const mapStateToProps = (state) => {
return {
isAuthenticated: state.user.isAuthenticated
};
}
export default connect(mapStateToProps, null)(AppNav)

Related

getServerSideProps not initialising client side state (next-redux-wrapper, redux/toolkit, redux-saga) Next.JS

I am doing a NextJS project using next-redux-wrapper, redux/toolkit and redux-saga.
This is my setup:
store/enquiry/slice.ts:
import { PayloadAction, createSlice } from '#reduxjs/toolkit'
import { HYDRATE } from 'next-redux-wrapper';
export enum LoadingTracker {
NotStarted,
Loading,
Success,
Failed
}
type EnquiryState = {
enquiries: Enquiry[],
loadingTracker: LoadingTracker
}
const initialState: EnquiryState = {
enquiries: [],
loadingTracker: LoadingTracker.NotStarted
}
export const enquirySlice = createSlice({
name: 'enquiries',
initialState,
reducers: {
//#ts-ignore
loadEnquiries: (state, action: PayloadAction<Enquiry[]>) => {
state.enquiries = action.payload;
state.loadingTracker = LoadingTracker.Success
},
failedLoadEnquiries: (state) => {
state.loadingTracker = LoadingTracker.Failed;
},
startedLoadingEnquiries: (state) => {
state.loadingTracker = LoadingTracker.Loading;
}
},
extraReducers:{
[HYDRATE]:(state, action) => {
return{
...state,
...action.payload.enquiry
};
}
},
});
export const { loadEnquiries, failedLoadEnquiries, startedLoadingEnquiries } =
enquirySlice.actions;
export default enquirySlice.reducer;
This is my enquiry saga setup: sagas/enquiry/saga.ts
import { call, put, takeLatest } from "redux-saga/effects";
import { loadEnquiries, startedLoadingEnquiries, failedLoadEnquiries } from
"../../store/enquiry/slice";
export function* loadEnquiriesSaga() {
try {
//#ts-ignore
let response = yield call(() =>
fetch("https://xxxxx686888wwg326et2.mockapi.io/enqueries")
);
if (response.ok) {
//#ts-ignore
let result = yield call(() => response.json());
yield put(loadEnquiries(result));
} else {
yield put(failedLoadEnquiries());
}
} catch (e) {
yield put(failedLoadEnquiries());
}
}
export function* loadEnquiriesWatcher() {
const { type } = startedLoadingEnquiries();
yield takeLatest(type, loadEnquiriesSaga);
}
This is my root saga setup: sagas/index.js
import { all } from 'redux-saga/effects';
import { loadEnquiriesWatcher } from './enquiry/saga';
export default function* rootSaga() {
yield all([
loadEnquiriesWatcher()
])
}
this is my store setup: store/index.js
import { configureStore, getDefaultMiddleware } from '#reduxjs/toolkit'
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
import createSagaMiddleware from "redux-saga";
import enquiryReducer from '../store/enquiry/slice';
import { createWrapper } from 'next-redux-wrapper';
import rootSaga from '../sagas/index';
const makeStore = () => {
const sagaMiddleware = createSagaMiddleware();
const store = configureStore({
reducer: {
enquiry: enquiryReducer,
},
middleware: [...getDefaultMiddleware({ thunk: false }), sagaMiddleware],
devTools: true
})
//#ts-ignore
store.sagaTask = sagaMiddleware.run(rootSaga);
return store;
}
const store = makeStore();
export type AppStore = ReturnType<typeof makeStore>;
export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch
export const useAppDispatch: () => AppDispatch = useDispatch
This is _app.ts file
import React, { useEffect } from "react";
import '../styles/globals.css'
import type { AppProps } from 'next/app'
import { QueryClient, QueryClientProvider } from "react-query";
import { ReactQueryDevtools } from "react-query/devtools";
import { Provider } from 'react-redux'
import { wrapper } from '../store/index';
const App = ({ Component, ...rest }: AppProps) => {
const [queryClient] = React.useState(() => new QueryClient());
const { store, props } = wrapper.useWrappedStore(rest);
const { pageProps } = props;
return (
<Provider store={store}>
<QueryClientProvider client={queryClient}>
<Component {...pageProps} />
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
</Provider>
);
}
export default App;
I am running a getServersideProps function in pages/index.js file.
import Head from 'next/head'
import { Inter } from '#next/font/google'
import utilStyles from '../styles/Utils.module.css';
import Layout from '../components/layout';
import { wrapper } from '../store';
import { startUserLogin } from '../store/user/slice';
import { END } from 'redux-saga';
import { GetServerSideProps } from 'next';
import { startedLoadingEnquiries } from '../store/enquiry/slice';
const inter = Inter({ subsets: ['latin'] })
export const getServerSideProps: GetServerSideProps = wrapper.getServerSideProps(
//#ts-ignore
(store) => async ({ req }) => {
await store.dispatch(startedLoadingEnquiries());
store.dispatch(END);
await (store as any).sagaTask.toPromise();
return {
props:{
status:1
}
}
})
export default function Home(props:any) {
return (
<Layout home>
<Head>
<title>Holiday Experts</title>
</Head>
<section className={utilStyles.headingMd}>
<p>Introduction to Holiday Exers blah blah blah............. status:
{props.status}</p>
</section>
<section className={`${utilStyles.headingMd} ${utilStyles.padding1px}`}>
<h2 className={utilStyles.headingLg}>To Do: List of Top Destinatons as
cards</h2>
</section>
</Layout>
)
}
When I got to the home page localhost:3000/, I see all the state values are populated. I go to localhost:3000/enquiries and i see a list of enquiries as well, but when I refresh, the list is empty because, client side state is not set. If I open Redux dev tools, I see enquiry state to be empty all the time.
I think there is something missing during the Hydration of the state. Not sure what it is.Can somebody help me with it?
Here are my references that I followed:
https://romandatsiuk.com/en/blog/post-next-redux-saga/
https://github.com/kirill-konshin/next-redux-wrapper

The email address is badly formatted - react native, firebase and redux

I'm trying to login using firebase and redux in react native. But It is giving error "The email address is badly formatted." If I dismiss the error and still give email and password, it gives error saying "The password is invalid or the user does not have a password". What might be the problem here?
If the firebase part is removed, the app works perfectly. The inputs works as usual.
Have a look at the video here
Code:
App.js
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import reduxThunk from 'redux-thunk';
import reducers from './src/reducers';
import LoginForm from './src/components/LoginForm';
import firebase from '#firebase/app';
import '#firebase/auth';
export default class App extends Component<Props> {
componentWillMount() {
const config = {
apiKey: 'xxxxxxxxxxxxxxx',
authDomain: 'xxxxxxxxxxxxxxx',
databaseURL: 'xxxxxxxxxxxxxxx',
storageBucket: 'xxxxxxxxxxxxxxx',
messagingSenderId: 'xxxxxxxxxxxxxxx'
};
firebase.initializeApp(config);
}
render() {
return (
<Provider store={createStore(reducers, {}, applyMiddleware(reduxThunk))}>
<LoginForm />
</Provider>
);
}
}
Action creators
import firebase from 'firebase';
import { EMAIL_CHANGED, PASSWORD_CHANGED, LOGIN_USER_SUCCESS } from './types';
export const emailChanged = (text) => {
return {
type: EMAIL_CHANGED,
payload: text
};
};
export const passwordChanged = (text) => {
return {
type: PASSWORD_CHANGED,
payload: text
};
};
export const loginUser = ({ email, password }) => {
return (dispatch) => {
firebase.auth().signInWithEmailAndPassword(email, password)
.then(user => {
dispatch({ type: 'LOGIN_USER_SUCCESS', payload: user });
});
};
};
LoginForm.js
import React, { Component } from 'react';
import { } from 'react-native';
import { connect } from 'react-redux';
import { Input, Button, Card, CardSection } from './common';
import { emailChanged, passwordChanged, loginUser } from '../actions';
import firebase from '#firebase/app';
import '#firebase/auth';
type Props = {};
class LoginForm extends Component<Props> {
onEmailChangeText = (text) => {
this.props.emailChanged(text);
}
onPasswordChangeText = (text) => {
this.props.passwordChanged(text);
}
onButtonPress = () => {
const { email, password } = this.props;
this.props.loginUser({ email, password });
}
render() {
return (
<Card>
<CardSection>
<Input
label='Email'
placeholder='email#gmail.com'
onChangeText={(text) => this.onEmailChangeText(text)}
value={this.props.email}
/>
</CardSection>
<CardSection>
<Input
label='Password'
placeholder='Password'
secureTextEntry
onChangeText={(text) => this.onPasswordChangeText(text)}
value={this.props.password}
/>
</CardSection>
<CardSection>
<Button onPress={this.onButtonPress()}>
Login
</Button>
</CardSection>
</Card>
);
}
}
const mapStateToProps = (state) => {
console.log('mapStateToProps', state.auth);
return { email: state.auth.email, password: state.auth.password, delete: state.auth.delete };
};
export default connect(mapStateToProps,
{ emailChanged, passwordChanged, loginUser })(LoginForm);
Reducer:
import { EMAIL_CHANGED, PASSWORD_CHANGED } from '../actions/types';
const INITIAL_STATE = { email: '', password: '', delete: '' };
export default (state = INITIAL_STATE, action) => {
console.log('emailReducer', state);
switch (action.type) {
case EMAIL_CHANGED:
return { ...state, email: action.payload };
case PASSWORD_CHANGED:
return { ...state, password: action.payload };
default:
return state;
}
};

react navigation "navigate" function not working inside firebase Asynchronous login function

I'm following the famous tutorial of "the-complete-react-native-and-redux-course",
i'm implementing react-navigation with redux and firebase, my problem is that its using the obsolete "react-native-router-flux" approach, i tried to follow it, but the project is not building at all.
I tried to migrate it step by step the the official react-navigation, the problem is, when trying to navigate from inside Asynchronous function (like firebase login function), navigation is not working, (putting in mind that i'm using redux)
**Update: Solution found, below is working code:
here is my Asynchronous function code (inside actions.js):
import firebase from 'firebase';
import { NavigationActions } from 'react-navigation'
import {
EMAIL_CHANGED,
PASSWORD_CHANGED,
LOGIN_USER_SUCCESS,
LOGIN_USER_FAIL,
LOGIN_USER
} from './types';
export const emailChanged = (text) => {
return {
type: EMAIL_CHANGED,
payload: text
};
};
export const passwordChanged = (text) => {
return {
type: PASSWORD_CHANGED,
payload: text
};
};
export const loginUser = ({email, password}, NavigationActions) => {
return (dispatch) => {
//indicate start user log in process
dispatch({type: LOGIN_USER});
firebase.auth().signInWithEmailAndPassword(email,password)
.then(user => loginUserSuccess(dispatch, user, NavigationActions))
.catch(() => {
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(user => loginUserSuccess(dispatch, user, NavigationActions))
.catch(() => loginUserFail(dispatch));
});
};
};
const loginUserFail = (dispatch) => {
dispatch({type: LOGIN_USER_FAIL});
}
const loginUserSuccess = (dispatch, user, NavigationActions) => {
dispatch({
type: LOGIN_USER_SUCCESS,
payload: user,
});
NavigationActions.navigate({ routeName: 'employeeList' })
};
and my router file:
import React from 'react';
import { StackNavigator } from 'react-navigation';
import LoginForm from './components/LoginForm';
import EmployeeList from './components/EmployeeList';
const Router = StackNavigator({
login: { screen: LoginForm },
employeeList: {screen: EmployeeList },
},
{
initialRouteName: 'login',
});
export default Router;
and App.js :
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import reducers from './reducers';
import firebase from 'firebase';
import ReduxThunk from 'redux-thunk';
//import LoginForm from './components/LoginForm';
import Router from './Router';
class App extends Component {
componentWillMount(){
const config = {
apiKey: "AIzaSyDV_vLg656D36E8T9GVraA6ZmZrcUi2QH4",
authDomain: "XXXXXXXXXX.firebaseapp.com",
databaseURL: "https://XXXXXXXXX.firebaseio.com",
projectId: "manager-ba44d",
storageBucket: "manager-ba44d.appspot.com",
messagingSenderId: "200262066369"
};
firebase.initializeApp(config);
}
render() {
const store= createStore(reducers, {}, applyMiddleware(ReduxThunk));
return (
<Provider store={store}>
<Router />
</Provider>
);
}
}
export default App;
my login component that calls the Asynch function:
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import { connect } from 'react-redux';
import { emailChanged, passwordChanged, loginUser } from '../actions';
import { Card, CardSection, Input, Button, Spinner } from './common';
class LoginForm extends Component {
static navigationOptions = () => ({
title: 'Login screen',
headerTitleStyle: {
textAlign:"center",
flex:1
}
});
onEmailChange(text){
this.props.emailChanged(text);
}
onPasswordChange(text){
this.props.passwordChanged(text);
}
onButtonPress(){
const {email, password, navigation} = this.props;
this.props.loginUser({email, password}, navigation);
}
renderError(){
if(this.props.error){
return(
<View style={{backgroundColor: 'white'}}>
<Text style={styles.errorTextStyle}>
{this.props.error}
</Text>
</View>
)
}
}
renderButton(){
if(this.props.loading){
return <Spinner size="large" />;
}
return (
<Button
style={styles.buttonStyle}
buttonText="Login" onPress={this.onButtonPress.bind(this)}>
</Button>
);
}
render(){
return(
<Card>
<CardSection>
<Input
label="Email"
placeholder="email#gmail.com"
onChangeText={this.onEmailChange.bind(this)}
value={this.props.email}
/>
</CardSection>
<CardSection>
<Input
secureTextEntry
label="password"
placeholder="password"
onChangeText={this.onPasswordChange.bind(this)}
value={this.props.password}
/>
</CardSection>
{this.renderError()}
<CardSection>
{this.renderButton()}
</CardSection>
</Card>
);
}
}
const mapStateToProps = state => {
return {
email: state.auth.email,
password: state.auth.password,
error: state.auth.error,
loading: state.auth.loading
};
};
export default connect(mapStateToProps,
{
emailChanged,
passwordChanged,
loginUser
})(LoginForm);
const styles = {
errorTextStyle: {
fontSize: 20,
alignSelf: 'center',
color: 'red'
},
buttonStyle:{
flex: 1,
flexDirection: 'row',
alignSelf: 'stretch'
}
}
UPDATE
You need to import NavigationActions like this
import { NavigationActions } from 'react-navigation'
export const loginUser = ({email, password}, navigation) => {
return (dispatch) => {
//indicate start user log in process
dispatch({type: LOGIN_USER});
firebase.auth().signInWithEmailAndPassword(email,password)
.then(user => loginUserSuccess(dispatch, user))
.then(NavigationActions.navigate('employeeList'))
.catch(() => {
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(user => loginUserSuccess(dispatch, user, navigation))
.catch(() => loginUserFail(dispatch));
});
};
};
const loginUserFail = (dispatch) => {
dispatch({type: LOGIN_USER_FAIL});
}
const loginUserSuccess = (dispatch, user, navigation) => {
dispatch({
type: LOGIN_USER_SUCCESS,
payload: user,
});
NavigationActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: 'employeeList' })],
}),
};

Action.type undefined redux

No matter what I do, I can't get rid of the mistake. I have often rewritten the actions but the error remains. I also wrote thunk at the top of the createstore. It would be great if you could support me a little bit.
My action, nothing special here only a fetch call to get my players
import fetch from "cross-fetch"
export const SET_PLAYERS = "setplayers"
export const setPlayers = players => {
return{
type: "setplayers",
players
}
}
export const fetchPlayers = () => (dispatch, getState) => {
return fetch("http://localhost:4444/api/players")
.then(response => response.json())
.then(players => {
dispatch(setPlayers(players))
}).catch(err => {
console.log("Could not fetch assortments" , err)
})
}
Component, at this point in time only a dummy to invoke the action:
import React from "react"
import PropTypes from "prop-types"
import { fetchPlayers } from "./action"
import { connect } from "react-redux"
import EnhancedTable from "../components/list/List"
import getPlayers from "./reducer"
class PlayerTable extends React.Component {
constructor(props) {
super(props)
this.state = {
}
}
componentDidMount(){
this.props.fetchPlayers()
}
render() {
console.log("#######", this.props.players)
return (
<EnhancedTable />
)
}
}
PlayerTable.propTypes = {
classes: PropTypes.object.isRequired,
}
const mapStateToProps = state => ({
players: getPlayers(state)
})
export default connect(mapStateToProps, { fetchPlayers })(PlayerTable)
Reducer
import { SET_PLAYERS } from "./action"
const setPlayers = (state={}, action) => {
console.log("ACTION", action)
switch (action.type) {
case SET_PLAYERS:
return {...state, players: action.players}
default:
return state
}
}
export default setPlayers
export const getPlayers = state => ([])
CombinedReducers
import { combineReducers } from "redux"
import { reducer as formReducer } from "redux-form"
import showProgressbar from "../components/progressbar/reducer"
import showSnackBar from "../components/snackbar/reducer"
import setPlayers from "../player/reducer"
export default combineReducers({
form: formReducer,
showProgressbar,
showSnackBar,
setPlayers
})
CreateStore
import App from "./App"
import React from "react"
import rootReducer from "./reducers"
import thunk from "redux-thunk"
import { render } from "react-dom"
import { createStore, applyMiddleware, compose } from "redux"
import { Provider } from "react-redux"
import { createLogger } from "redux-logger"
const store = createStore(
rootReducer,
compose(applyMiddleware(thunk),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
))
render(
<Provider store={store}>
<App />
</Provider>,
/* eslint-disable*/
document.getElementById("root")
/* eslint-enable */
)
You've defined mapStateToProps properly, but don't you need to do the same with mapDispatchToProps for the second argument to connect()?
const mapStateToProps = state => ({
players: getPlayers(state)
})
const mapDispatchToProps = dispatch => ({
fetchPlayers() {
dispatch(fetchPlayers())
}
})
export default connect(mapStateToProps, mapDispatchToProps)(PlayerTable)

authentication is not working with firebase using react-native-redux + redux-thunk

the code is working and app also showing on mobile but the problem is that the authentication is always failed even i entered the correct email/pass.
this authAction.js file.
import firebase from 'firebase';
import { LOGIN_USER_FAIL, EMAIL_CHANGED , PASSWORD_CHANGED , LOGIN_USER_SUCCESS, LOGIN_USER } from './types';
import { Actions } from 'react-native-router-flux';
//here define the actionCreator of email
export const emailChanged = (text) => {
return {
//type of action defined in type.js file
type: 'EMAIL_CHANGED',
payload: text
};
};
//here define the actionCreator of password
export const passwordChanged = (text) => {
return {
//type of action defined in type.js file
type: 'PASSWORD_CHANGED',
payload: text
};
};
export const loginUser = ({ email, password}) => {
return (dispatch) => {
dispatch({type: LOGIN_USER});
firebase.auth().signInWithEmailAndPassword(email, password)
.then(user => loginUserSuccess(dispatch, user))
.catch( () => {
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(user => loginUserSuccess(dispatch, user) )
.catch(() => loginUserFail(dispatch));
});
};
};
const loginUserFail = (dispatch) => {
dispatch({type: LOGIN_USER_FAIL});
Actions.main();
};
const loginUserSuccess = ( dispatch, user) => {
dispatch({
type: LOGIN_USER_SUCCESS,
payload: user
});
};
this is types.js file where i stored all the strings in variables
export const EMAIL_CHANGED = 'email_changed';
export const PASSWORD_CHANGED = 'password_changed';
export const LOGIN_USER_SUCCESS = 'login_user_success';
export const LOGIN_USER_FAIL = 'login_user_fail';
export const LOGIN_USER = 'login_user';
this is authReducer.js file
import { EMAIL_CHANGED , PASSWORD_CHANGED, LOGIN_USER_SUCCESS, LOGIN_USER_FAIL, LOGIN_USER } from '../actions/types';
const INITIAL_STATE = { email: '', password: '', user: null, error: '', loading: false };
export default (state= INITIAL_STATE, action) => {
switch(action.type){
//..state isto update the state object
case EMAIL_CHANGED:
return { ...state, email: action.payload};
case PASSWORD_CHANGED:
return { ...state, password: action.payload };
case LOGIN_USER_SUCCESS:
return { ...state, user : action.payload, error:'', loading: false};
case LOGIN_USER_FAIL:
return { ...state, error: 'Authentication Failed', password: '', loading: false };
case LOGIN_USER:
return { ...state, loading: true, error: '' };
default:
return state;
}
};
this is app.js file where i inserted the firebase API
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';
import { createStore, applyMiddleware } from 'redux';
import firebase from 'firebase'
import rootReducer from './reducers';
import LoginForm from './components/LoginForm';
class App extends Component {
componentWillMount() {
firebase.initializeApp({
apiKey: 'AIzaSyAe45P2xc8q09gpEV6oA6s4U9YjnaTf9vc',
authDomain: 'manager-6cde7.firebaseapp.com',
databaseURL: 'https://manager-6cde7.firebaseio.com',
projectId: 'manager-6cde7',
storageBucket: 'manager-6cde7.appspot.com',
messagingSenderId: '408722531799'
});
}
render()
{
const store = createStore(rootReducer,applyMiddleware(thunk));
return(
<Provider store={store} >
<LoginForm />
</Provider>
);
}
}
export default App;
this is loginForm.js file.
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { emailChanged, passwordChanged, loginUser } from '../actions';
import { Button, Card, CardSection, Input, Spinner } from './common';
import { Text } from 'react-native';
class LoginForm extends Component {
onEmailChange(text){
//now call the actionCreator in actions index.js
this.props.emailChanged(text);
}
onPasswordChanged(text){
//now call the actionCreator in actions index.js
this.props.passwordChanged(text);
}
onButtonPress() {
const {email, password} = this.props;
this.props.loginUser({email, password});
}
renderButton(){
if(this.props.loading)
{
return <Spinner size="large" />;
}
return (
<Button onPress={this.onButtonPress.bind(this)} >LogIn</Button>
);
}
render(){
return(
<Card>
<CardSection>
<Input
onChangeText={this.onEmailChange.bind(this)}
label="Email"
placeholder="email#gmail.com"
value={this.props.email}
/>
</CardSection>
<CardSection>
<Input
value={this.props.password}
onChangeText={this.onPasswordChanged.bind(this)}
secureTextEntry
label="Password"
placeholder="******"
/>
</CardSection>
<Text style={styles.errorAuthentication}>{this.props.error}</Text>
<CardSection>
{this.renderButton()}
</CardSection>
</Card>
);
}
}
const mapStateToProps = ({auth}) => {
const { email, password, error, loading } = auth;
return {
email, password, error, loading };
};
const styles = {
errorAuthentication: {
fontSize: 20,
color: 'red',
alignSelf: 'center'
}
};
export default connect(mapStateToProps, { emailChanged, passwordChanged, loginUser })(LoginForm);

Resources