Show user info on login - react native - react-native

I have my login working, it logs me in without problems and it enters the screen that I want, but when I want to show the information on the screen of the user that logs in, I have not been able to show the user information on the screen that it should load from database. I have tried to create an interface where I add the names of the fields as they are in the database but when calling them from my screen nothing is loaded
what I need is that when I log in to my screen protectedScreen.ts it shows me the data of the user that logs in
mi db: Tabla : usuarios campos: id, name, email, password, tipo_usuario
AuthContext.ts //where valid and login
import React,{ createContext, useEffect, useReducer } from "react";
import AsyncStorage from '#react-native-async-storage/async-storage';
import { SafeAreaView, StyleSheet, TextInput, View, Alert, TouchableOpacity, Text } from "react-native";
import cafeApi from "../api/cafeApi";
import { LoginData, LoginResponse, RegisterData, Usuarios } from "../interfaces/appinterfaces";
import { authReducer, AuthState } from "./AuthReducer";
type AuthContextProps = {
errorMessage: string;
token: string | null;
user: Usuarios | null;
status: 'checking' | 'authenticated' | 'not-authenticated';
signUp: (RegisterData: RegisterData) => void;
signIn: (loginData : LoginData) => void;
logOut: () => void;
removeError: () => void;
}
const authInicialState: AuthState = {
status:'checking',
token: null,
user: null,
errorMessage:''
}
export const AuthContext = createContext({} as AuthContextProps);
export const AuthProvider = ({children}: any) =>{
const[state, dispatch] = useReducer(authReducer,authInicialState);
useEffect(() =>{
checkToken();
}, [])
const checkToken = async () =>{
const token = await AsyncStorage.getItem('token');
//No token, no autenticado
if (!token) return dispatch({ type:'notAuthenticated'});
//hay token
const resp = await cafeApi.get('/usuarios/middlewares/Auth.php');
if(resp.status !== 200){
return dispatch({type:'notAuthenticated'});
}
await AsyncStorage.setItem('token', resp.data.token)
dispatch({
type: 'signUp',
payload:{
token: resp.data.token,
user: resp.data.usuarios
}
})
}
const signIn = async({correo, password}: LoginData) => {
try {
await fetch('https://www.miweb.com/apiPlooy/usuarios/login.php',
{
method:'POST',
headers:{
'Accept': 'application/json',
'content-Type': 'application/json'
},
body: JSON.stringify({"email":correo, "password" : password})
}).then(res => res.json())
.then(resData => {
if(resData.message == "Ha iniciado sesiĆ³n correctamente.") {
dispatch({
type: 'signUp',
payload: {
token: resData.token,
user: resData.usuarios
}
});
}else{
Alert.alert(resData.message)
}
});
}catch (error) {
dispatch({type: 'addError',
payload: error.response.data.msg || 'InformaciĆ³n incorrecta'})
}
};
return(
<AuthContext.Provider value={{
...state,
signUp,
signIn,
logOut,
removeError,
}}>
{children}
</AuthContext.Provider>
)
}
appinterfaces.ts // where I add the user db fields to be able to show them on the screen when I login
export interface LoginData{
correo: string;
password: string;
}
export interface LoginResponse{
usuarios: Usuarios;
token: string;
}
export interface Usuarios{
tipo_usuario: String;
email: String;
password: String;
name: String
}
ProtectedScreen.ts // This is my screen when I log in and where I want to show some field of my user that I log in but it is not shown.
interface Props extends StackScreenProps<any, any>{}
export const ProtectedScreen = ({navigation}: Props) => {
const {user, token} = useContext(AuthContext);
const {email, password, name, onChange} = useForm({
email:'',
password:'',
name:'',
});
return (
<>
<View style={loginStyles.formContainer}>
<Text>BIENVENIDO
Tipo usuario: {JSON.stringify(user.tipo_usuario, null, 50)}
</Text>
</View>
</>
)
}
code and api: https://github.com/Giovannychvz/react-native
//I add what I have found in case it is of any use I have a project in reactjs and it uses the same api as the react native project and when I log in it loads the data of the user who logged in, I don't know if it is of any use but I send the context of react:
Note: the only strange thing I found in this context of react is that user-info.php is being called and I am not calling this file from react native because the problem must be there but I have not been able to solve it.
context.js
import React, { createContext,Component } from "react";
import axios from 'axios'
import history from '../components/history';
export const MyContext = createContext();
// Define the base URL
const Axios = axios.create({
baseURL: 'https://www.miweb.com/apiPlooy/usuarios/',
});
class MyContextProvider extends Component{
constructor(){
super();
this.isLoggedIn();
history.push('/');
}
// Root State
state = {
showLogin:true,
isAuth:false,
theUser:null,
}
// Toggle between Login & Signup page
toggleNav = () => {
const showLogin = !this.state.showLogin;
this.setState({
...this.state,
showLogin
})
}
// On Click the Log out button
logoutUser = () => {
localStorage.removeItem('loginToken');
localStorage.clear();
history.push('/');
this.setState({
...this.state,
isAuth:false
})
}
registerUser = async (user) => {
// Sending the user registration request
const register = await Axios.post('register.php',{
name:user.name,
email:user.email,
password:user.password
});
return register.data;
}
loginUser = async (user) => {
// Sending the user Login request
const login = await Axios.post('login.php',{
email:user.email,
password:user.password
});
return login.data;
}
// Checking user logged in or not
isLoggedIn = async () => {
const loginToken = localStorage.getItem('loginToken');
// If inside the local-storage has the JWT token
if(loginToken){
//Adding JWT token to axios default header
Axios.defaults.headers.common['Authorization'] = 'bearer '+loginToken;
// Fetching the user information
const {data} = await Axios.get('user-info.php');
// If user information is successfully received
if(data.success && data.user){
this.setState({
...this.state,
isAuth:true,
theUser:data.user
});
}
}
}
render(){
const contextValue = {
rootState:this.state,
toggleNav:this.toggleNav,
isLoggedIn:this.isLoggedIn,
registerUser:this.registerUser,
loginUser:this.loginUser,
logoutUser:this.logoutUser
}
return(
<MyContext.Provider value={contextValue}>
{this.props.children}
</MyContext.Provider>
)
}
}
export default MyContextProvider;

Related

how to get a user by id with a get request to express using react native?

I am trying to render One users info for the profile page in react native using express and axios.
This is the controller responsible for getting a user.
// GET ONE USER BY ID
module.exports.findOneSingleUser = (req, res) => {
User.findOne({ _id: req.params.id })
.then(oneSingleUser => res.json({ user: oneSingleUser }))
.catch(err => res.json({ message: 'Something went wrong', error: err }));
}
this is the code im using to make the axios request to the server and I am able to get all the users in the DB but I want to be able to render one user by id or the token that is stored for login and for login to persist which is working.
const ProfileInfo = (props) => {
const { navigation, route } = props
const authCtx = useContext(AuthContext);
const token= authCtx.token
const [userInfo, setUserInfo] = useState([]);
useEffect(() => {
axios.get(`http://localhost:3000/api/users/`)
.then(res => console.log(res.data))
.catch(err => console.log(err))
}, [])
this is the code in util folder that gets the token from the backend
import axios from 'axios'
import { useNavigation } from '#react-navigation/native';
const BASE_URL = 'http://localhost:3000'
// ! LOGIN FUNCTION
export async function authenticate(email,password ){
const token = await axios.post(BASE_URL + '/api/login',
{
email: email,
password: password,
},{ withCredentials: true }
);
return token;
}
// ! REGISTER NEW USER FUNCTION
export async function createUser(email, password) {
const token = await axios.post(BASE_URL + '/api/register',
{
email: email,
password: password,
},{ withCredentials: true }
);
return token;
}
this is the screen where I have the profile info component being used
import React,{useEffect} from 'react'
import ProfileInfo from '../components/Profile/ProfileInfo';
import Statistics from '../components/Profile/Statistics';
const ProfileScreen = (props) => {
const {navigation} = props
return (
<>
<ProfileInfo navigation={navigation}/>
<Statistics />
</>
)
}
export default ProfileScreen
How do or What do I need to pass into the url of the axios request to get the data for the user that is logged in? thanks in advance.
when I change the server side to
User.findOne({ token: req.params.token})
&
useEffect(() => {
axios.get(`http://localhost:3000/api/users/${token}`)
.then(res => console.log(res.data))
.catch(err => console.log(err))
}, [])
I get a user but it is only the first user in DB not the user that is logged in... not sure how to get the one user that is logged in.

Issue while trying to post / get an API on expo

I'm new to react-native and it's my first app.
I'm trying to develop my app and connect it to my API. I develop all my app with the navigator view on Expo and there is no problem, the connection is good and I can get or post everything.
Now that I'm trying to fetch it with expo on my Android or Apple, there is no response.
Here is my code for the authentication:
login.js
import { post } from '../request/post';
export const login = (mail, pass) => {
console.log(mail)
console.log(pass)
console.log("POST request for login");
return post('/api/login', {
email: mail,
password: pass,
mobile: true
});
};
post.js
import { API_URL } from '../url';
import { getStorageToken } from '../../utils/asyncStorage';
const getHeaders = async () => {
const token = await getStorageToken();
const headers = {
Accept: 'application/json',
'Content-Type': 'application/json'
};
if (token !== 'undefined' && token.length > 0) {
headers['auth'] = `${token}`;
}
return headers;
};
export const post = async (destination, body) => {
const headers = await getHeaders();
const result = await fetch(`${API_URL}${destination}`, {
method: 'POST',
headers,
body: JSON.stringify(body),
});
console.log(result);
if (result.ok) {
return await result.json();
}
throw { error: result.status };
};
loginPage.js
import React from 'react';
import { View, Text, TouchableOpacity, StyleSheet, ScrollView, Image, TextInput, Linking } from 'react-native';
import { setStorageAfterConnection } from '../../utils/asyncStorage';
import { CheckBox, Icon } from 'react-native-elements';
import { login } from '../../api/auth/login';
export default class LogIn extends React.Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: '',
errorMessage: ''
};
}
submit = () => {
login(this.state.email, this.state.password)
.then(async (res) => {
await setStorageAfterConnection(res);
this.props.navigation.navigate('Home');
})
.catch((res) => {
if (res && res.error) {
this.setState({ errorMessage: res.error});
}
this.setState({ errorMessage: "Erreur de connexion"});
});
};
render() {
return (
...............................................
);
}
}
I tried to debug it and it seems to not find the function post() because I don't have any network request. I do not know what's the correct way to do an "API" component so I think I probably made some mistakes but I didn't find what I'm missing.
I used Lan connection and my API isn't hosted on local.
Regards,
Try to add async-await to "login":
export const login = async (mail, pass) => { <---- 'async' ADDED
console.log(mail)
console.log(pass)
console.log("POST request for login");
return await post('/api/login', { <---- 'await' ADDED
email: mail,
password: pass,
mobile: true
});
};
I tried to put some debug on my code:
export const post = async (destination, body) => {
console.log("A");
const headers = await getHeaders();
console.log("B")
const result = await fetch(`${API_URL}${destination}`, {
method: 'POST',
headers,
body: JSON.stringify(body),
});
console.log(result);
if (result.ok) {
return await result.json();
}
throw { error: result.status };
};
And I get on the console:
email
password
POST request for login
A
So the problem seems to be on my await getHeaders()
EDIT: Problem was solved. It was because of the getHeaders that try to get the token and failed.

React Native accessing SecureStore

I have searched Google for a clear answer on this but cant find one. Below is my code.
In a previous screen I have stored the token to SecureStore
I'm now trying to access it from a different screen.
(async () => {
const token = await SecureStore.getItemAsync('token');
return token;
})();
export default class App extends React.Component {
constructor(){
super();
this.state = {
data: [],
loaded: true,
error: null,
token: token
}
}
Can anyone advise me how to get the value from SecureStore to my state inside the class?
Entire Code
import React, { Component} from 'react';
import { Text, Button, ScrollView } from 'react-native';
import { globalStyles } from '../styles/global';
import * as SecureStore from 'expo-secure-store';
(async () => {
const token = await SecureStore.getItemAsync('token');
//console.log('token output 1 ' + token);
return token;
})();
export default class App extends React.Component {
constructor() {
super();
this.state = {
data: [],
loaded: true,
error: null,
token: ""
};
}
baseURL = 'https://www.example.co.uk/api/auth';
getData = (ev)=>{
this.setState({loaded:false, error: null});
let url = this.baseURL + '/list';
let h = new Headers();
console.log('token output 2 = ' + this.state.token);
h.append('Authorization', 'Bearer tokenToBePutHere');
h.append('Content-Type', 'application/json');
h.append('X-Requested-With', 'XMLHttpRequest');
let req = new Request(url, {
headers: h,
method: 'GET'
});
fetch(req)
.then(response=>response.json())
.then(this.showData)
.catch(this.badStuff)
}
showData = (data)=>{
this.setState({loaded:true, data:data});
}
badStuff = (err) => {
this.setState({loaded: true, error: err.message});
}
componentDidMount() {
(async () => {
const token = await SecureStore.getItemAsync('token');
this.setState({ token });
})();
this.getData();
}
render() {
return (
<ScrollView style={globalStyles.container}>
{ !this.state.loaded && (
<Text>LOADING</Text>
)}
<Text>Your Lists Are:</Text>
{/*} <Button title="Get Data"
onPress={this.getData} /> */}
{ this.state.error && (
<Text style={styles.err}>{this.state.error}</Text>
)}
{ this.state.data && this.state.data.length > 0 && (
this.state.data.map( data => (
<Text key={data.id}>
{ data.lists.name }
</Text>
))
)}
</ScrollView>
);
}
}
I have added all of my code for this screen.
token Output 1 works and outputs the correct token
token Output 2 does not work and returns nothing.
I need to use the token in the api call but cant get it to pass there.
You can use the lifecycle method componentDidMount and callbacks like this:
export default class App extends React.Component {
constructor() {
super();
this.state = {
data: [],
loaded: true,
error: null,
token: ""
};
}
componentDidMount() {
SecureStore.getItemAsync("token").then(token => {
this.setState({ token });
});
}
// ...
}
Same solution using async/await:
class App extends React.Component {
constructor() {
super();
this.state = {
data: [],
loaded: true,
error: null,
token: '',
};
}
componentDidMount() {
(async () => {
const token = await SecureStore.getItemAsync('token');
this.setState({ token });
})();
}
// ...
}
Addressing updated question
If you need only need the token for the fetch request you don't even need to store the token in the state. You can use it directly after retrieving it from SecureStore:
componentDidMount() {
(async () => {
const token = await SecureStore.getItemAsync('token');
// Your fetch code
this.setState({loaded:false, error: null});
let url = this.baseURL + '/list';
let h = new Headers();
h.append('Authorization', `Bearer ${token}`);
h.append('Content-Type', 'application/json');
h.append('X-Requested-With', 'XMLHttpRequest');
let req = new Request(url, {
headers: h,
method: 'GET'
});
fetch(req)
.then(response=>response.json())
.then(() => this.setState({loaded:true, data:data}))
.catch(() => this.badStuff())
})();
}

Handling Refresh Token in React Native

I have an app authenticating fine and returning the access_token and refresh_token. I store them with AsyncStorage and save/get the access_token with redux. This is the very first app I am building and I am struggling with how and where to use the refresh_token.
This is the axios call in the component loginForm.js
axios({
url: `${base}/oauth/token`,
method: 'POST',
data: formData,
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data',
}
})
.then(response => {
setStatus({ succeeded: true });
// console.log(response.data);
deviceStorage.saveKey("userToken", response.data.access_token);
deviceStorage.saveKey("refreshToken", response.data.refresh_token);
Actions.main();
})
.catch(error => {
if (error.response) {
console.log(error);
}
});
This is the service deviceStorage.js
import { AsyncStorage } from 'react-native';
const deviceStorage = {
async saveItem(key, value) {
try {
await AsyncStorage.setItem(key, value);
} catch (error) {
console.log('AsyncStorage Error: ' + error.message);
}
}
};
export default deviceStorage;
This is the token action file
import { AsyncStorage } from 'react-native';
import {
GET_TOKEN,
SAVE_TOKEN,
REMOVE_TOKEN,
LOADING_TOKEN,
ERROR_TOKEN
} from '../types';
export const getToken = token => ({
type: GET_TOKEN,
token,
});
export const saveToken = token => ({
type: SAVE_TOKEN,
token
});
export const removeToken = () => ({
type: REMOVE_TOKEN,
});
export const loading = bool => ({
type: LOADING_TOKEN,
isLoading: bool,
});
export const error = tokenError => ({
type: ERROR_TOKEN,
tokenError,
});
export const getUserToken = () => dispatch =>
AsyncStorage.getItem('userToken')
.then((data) => {
dispatch(loading(false));
dispatch(getToken(data));
})
.catch((err) => {
dispatch(loading(false));
dispatch(error(err.message || 'ERROR'));
});
export const saveUserToken = (data) => dispatch =>
AsyncStorage.setItem('userToken', data)
.then(() => {
dispatch(loading(false));
dispatch(saveToken('token saved'));
})
.catch((err) => {
dispatch(loading(false));
dispatch(error(err.message || 'ERROR'));
});
export const removeUserToken = () => dispatch =>
AsyncStorage.removeItem('userToken')
.then((data) => {
dispatch(loading(false));
dispatch(removeToken(data));
})
.catch((err) => {
dispatch(loading(false));
dispatch(error(err.message || 'ERROR'));
});
This is the token reducer file
import {
GET_TOKEN,
SAVE_TOKEN,
REMOVE_TOKEN,
LOADING_TOKEN,
ERROR_TOKEN
} from '../actions/types';
const INITIAL_STATE = {
token: {},
loading: true,
error: null
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case GET_TOKEN:
return {
...state,
token: action.token
};
case SAVE_TOKEN:
return {
...state,
token: action.token
};
case REMOVE_TOKEN:
return {
...state,
token: action.token
};
case LOADING_TOKEN:
return {
...state,
loading: action.isLoading
};
case ERROR_TOKEN:
return {
...state,
error: action.error
};
default:
return state;
}
};
And this is the authentication file
import React from 'react';
import {
StatusBar,
StyleSheet,
View,
} from 'react-native';
import { connect } from 'react-redux';
import { Actions } from 'react-native-router-flux';
import { Spinner } from '../common';
import { getUserToken } from '../../actions';
class AuthLoadingScreen extends React.Component {
componentDidMount() {
this.bootstrapAsync();
}
bootstrapAsync = () => {
this.props.getUserToken().then(() => {
if (this.props.token.token !== null) {
Actions.main();
} else {
Actions.auth();
}
})
.catch(error => {
this.setState({ error });
});
};
render() {
return (
<View style={styles.container}>
<Spinner />
<StatusBar barStyle="default" />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
},
});
const mapStateToProps = state => ({
token: state.token,
});
const mapDispatchToProps = dispatch => ({
getUserToken: () => dispatch(getUserToken()),
});
export default connect(mapStateToProps, mapDispatchToProps)(AuthLoadingScreen);
I believe I need to create an action and reducer to get the refresh_token (is that correct?) but I do not know what to do with it and where to call it (perhaps in the authentication file?).
Any help with this possibly with code examples related to my code would be massively appreciated. Thanks
Below are the steps
Do Login , get accessToken , refreshToken from response and save it to AsyncStorage.
Make common function for API calling
async function makeRequest(method, url, params, type) {
const token = await AsyncStorage.getItem('access_token');
let options = {
method: method,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: 'Bearer ' + token,
},
};
if (!token) {
delete options['Authorization'];
}
if (['GET', 'OPTIONS'].includes(method)) {
url += (url.indexOf('?') === -1 ? '?' : '&') + queryParams(params);
} else {
Object.assign(options, {body: JSON.stringify(params)});
}
const response = fetch(ENV.API_URL+url, options);
return response;
}
Make one method in redux for getAceessTokenFromRefreshToken.
Use this method when session is expired
How do you know session is expired?
From each API calling if you get response like (440 response code) in
async componentWillReceiveProps(nextProps) {
if (nextProps.followResponse && nextProps.followResponse != this.props.followResponse) {
if (nextProps.followResponse.status) {
if (nextProps.followResponse.status == 440) {
// call here get acceesstokenfrom refresh token method and save again accesstoken in asyncstorage and continue calling to API
}
}
}
}

"Redux is not working properly with login"

I have implemented redux with my login form which is not working properly
it shows ERROR 'Cannot read property 'isAuthenticated' of undefined. which i think it means that redux is not implemented properly.
Please Help!
if you need any other file,tell me i will share it to you.
LoginForm.js
import React, {Component} from 'react';
import {
//StyleSheet,
View,
Text,
TextInput,
Button
} from 'react-native';
import {reduxForm,Field} from 'redux-form';
import {connect} from 'react-redux';
import {login} from './authActions';
const validate = values =>{
const errors = {};
if(!values.email){
errors.email="Please fill the email"
return errors;
}
if(!values.password){
errors.password="Please fill the password"
return errors;
}
}
const myFields = ({label,meta:{error,touched}, input:{onChange}}) =>{
return(
<View>
<Text>{label}</Text>
<TextInput style={{borderWidth:1,width:300,marginBottom:10}}
onChangeText={onChange}/>
{touched && (error && (<Text style={{color:'red'}}>{error}</Text>))}
</View>
);
}
const passFields = ({label,meta:{error,touched}, input:{onChange}}) =>{
return(
<View>
<Text>{label}</Text>
<TextInput style={{borderWidth:1,width:300,marginBottom:10}}
secureTextEntry={true}
onChangeText={onChange}/>
{touched && (error && (<Text style={{color:'red'}}>{error}</Text>))}
</View>
);
}
const submitbtn = values =>{
//alert(`here are the values ${JSON.stringify(values)}`);
//console.log(input.value);
this.props.login(values);
}
const myLoginForm = props => {
const {handleSubmit} = props;
return(
<View>
<Field
name="email"
component={myFields}
label="Email"/>
<Field
name="password"
component={passFields}
label="Password"
/>
<Button title="Submit"
onPress={handleSubmit(submitbtn)}/>
</View>
);
}
const LoginForm = reduxForm({
form:'loginform',
validate
})(myLoginForm);
const mapStateToProps =(state) =>({
isAuthenticated: state.auth.isAuthenticated
});
export default connect(mapStateToProps,{login})(LoginForm);
authActions.js
import axios from 'axios';
//import { returnErrors } from './errorActions';
export const register = ({username, name, email, password}) => {
return (dispatch, getState) => {
const config = {
headers : {
'Content-type' : 'Application/json'
}
}
const body = JSON.stringify({
username,
name,
email,
password
})
axios.post('http://localhost:5000/users/register', body , config )
.then(res => dispatch({
type : 'REGISTER_SUCCESS',
payload : res.data
}))
.catch(err => {
dispatch(returnErrors(err.response.data, err.response.status, 'REGISTER_FAIL'));
dispatch({
type : 'REGISTER_FAIL'
})
});
};
};
export const login = ({username, password}) => {
return (dispatch, getState) => {
const config = {
headers : {
'Content-type' : 'Application/json'
}
}
const body = JSON.stringify({
username,
password
})
axios.post('http://localhost:5000/users/login', body , config )
.then(res => dispatch({
type : 'LOGIN_SUCCESS',
payload : res.data
}))
.catch(err => {
dispatch(returnErrors(err.response.data, err.response.status, 'LOGIN_FAIL'));
dispatch({
type : 'LOGIN_FAIL'
})
});
};
}
export const logout = () => {
return {
type : 'LOGOUT_SUCCESS'
}
}
export const loadUser = () => {
return (dispatch, getState) => {
dispatch({
type: 'USER_LOADING',
});
axios.get('http://localhost:5000/users/auth' , tokenConfig(getState))
.then(res => dispatch({
type: 'USER_LOADED',
payload : res.data
}))
.catch(err => {
dispatch(returnErrors(err.response.data.message, err.response.status));
dispatch({
type : 'AUTH_ERROR'
});
})
}
}
//
export const tokenConfig = (getState) => {
const token = getState().auth.token;
const config = {
headers : {
'content-type' : 'Application/json',
}
}
if(token) {
config.headers['auth'] = token;
}
return config;
}
authReducer.js
const initState = {
toke: localStorage.getItem('token'),
isAuthenticated: null,
isLoading: null,
user: null
};
const authReducer = (state = initState, action) => {
switch(action.type){
case 'USER_LOADING':
return{
...state,
isLoading: true
}
case 'USER_LOADED':
return{
...state,
isLoading: false,
isAuthenticated:true,
user:action.payload
}
case 'REGISTER_SUCCESS':
case 'LOGIN_SUCCESS':
localStorage.setItem('token', action.payload.token)
return{
...state,
...action.payload,
isLoading: false,
isAuthenticated:true,
}
case 'AUTH_ERROR':
case 'LOGOUT_SUCCESS':
case 'LOGIN_FAIL':
case 'REGISTER_FAIL':
localStorage.removeItem('token')
return{
token: null,
user: null,
isLoading: false,
isAuthenticated:false,
}
default:
return state;
}
}
export default authReducer
Please check file where you combine your reducers, there's possibility that you put your reducer as something other than "auth" or even you forgotten to put the reducer here.
You can install "redux-devtools-extension" package and it's chrome extension to see which reducers are connected to your redux state and debug it more easily. Also, redux-form requires you to pass the form reducer you create along with all the other reducers you have in 'combineReducers'. Follow the instructions on their docs https://redux-form.com/8.2.2/docs/gettingstarted.md/
hope this helps :)