Why does the user getting redirected to the login page on refresh? - javascript

Okay, there's this simple REACTJS app, where firebase is used.
There once you login everything works fine except when you hit the refresh icon. The moment you do it, it redirects you to the previous place where you were asked to login. That's the problem that this newly-born coder is trying to solve!
I can give you following snippets of code:
This is of the landing page
function Landing() {
const [{ }, dispatch] = useStateValue();
firebase.auth().setPersistence(firebase.auth.Auth.Persistence.NONE)
// .then(function () {
// console.log("successfully set the persistence");
// return firebase.auth().signInWithPopup(provider);
// })
.catch(function (error) {
console.log("failed to ser persistence: " + error.message)
});
firebase.auth().onAuthStateChanged((user) => {
if (user) {
console.log('user is logged in');
} else {
console.log('user is logged out now')
}
});
const signIn = () => {
auth
.signInWithPopup(provider)
.then((result) => {
dispatch({
type: actionTypes.SET_USER,
user: result.user
})
}).catch((error) => alert(error.message))
}
reducer.js snippet
export const initialState = {
user: null,
}
export const actionTypes = {
SET_USER: 'SET_USER',
LOGOUT_USER: 'LOGOUT_USER'
}
const reducer = (state, action) => {
console.log(action)
switch (action.type) {
case actionTypes.SET_USER:
return {
...state,
user: action.user,
}
case actionTypes.LOGOUT_USER:
return {
...state,
user: null,
}
default:
return state;
This is of firebase.js
Yes, Google Authentication is what's being used here
import firebase from 'firebase';
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
//config
};
// const user = firebase.auth().currentUser;
// console.log(user);
const firebaseApp = firebase.initializeApp(firebaseConfig)
const db = firebaseApp.firestore();
const storage = firebase.storage();
const auth = firebaseApp.auth();
const provider = new firebase.auth.GoogleAuthProvider();
export default db;
export { auth, provider, storage }
Finally here is of the app.js
function App() {
const [{ user }, dispatch] = useStateValue();
console.log(user);
return (
<div className="app">
{!user ? (
<Landing />
) : (
<App />
)
</div>
Your attention to this matter is greatly appreciated!
Oh by the way this following question is also related to this. It might help you to get a better idea of this issue. So make sure to take a look at that as well!
How can you persist a logged-in user with firebase?
Thanks again!

sample code. work
import firebase from 'firebase/app';
import 'firebase/auth';
import { useEffect, useState } from 'react';
import firebaseConfig from './firebase-config';
const firebaseApp = firebase.initializeApp(firebaseConfig);
const googleProvider = new firebase.auth.GoogleAuthProvider();
firebaseApp.auth().setPersistence(firebase.auth.Auth.Persistence.SESSION)
.then(function () {
// return firebaseApp.auth().signInWithPopup(googleProvider)
})
.catch(function (error) {
console.log(error)
});
function App() {
const [user, setUser] = useState(null)
useEffect(() => {
firebaseApp.auth().onAuthStateChanged((res) => {
console.log("onAuthStateChanged", res)
if (res) {
setUser(res)
// console.log('user is logged in', user);
} else {
setUser(null)
// console.log('user is logged out now')
}
});
}, [])
const signInWithGoogle = (e) => {
firebaseApp.auth()
.signInWithPopup(googleProvider)
.then((result) => {
// console.log(result)
// setUser(result.additionalUserInfo)
}).catch(err => {
// console.log(err)
})
}
const signOut = (e) => {
firebaseApp.auth().signOut()
}
return (
<div>
<h1>Firebase Authentication</h1>
{
user
? (
<div>
<p>Hello, {user.displayName}</p>
<button onClick={signOut}>Sign out</button>
</div>
)
: (
<div>
<p>Please sign in.</p>
<button onClick={signInWithGoogle}>Sign in with Google</button>
</div>
)
}
</div>
);
}
export default App;

Related

Messages don't show on the website, only stores in Firestore Database

When I send a message, it doesn't display on the website, it only stores in Firestore. I changed the rules and indexes, I'll type here the essential parts of my code which may cause this to happen.
MainPage.jsx:
import React, { useEffect, useRef, useState } from "react";
import {
query,
collection,
orderBy,
onSnapshot,
limit,
where,
} from "firebase/firestore";
import { db } from "../components/base";
import Chat from "../pages/Chat";
import SendMessage from "../pages/SendMessage";
import { useNavigate } from "react-router-dom";
const MainPage = () => {
const [messages, setMessages] = useState([]);
const scroll = useRef();
let navigate = useNavigate();
const [userIdToken, setUserIdToken] = useState(
sessionStorage.getItem("ID Token")
);
const handleLogout = () => {
sessionStorage.removeItem("Auth Token");
sessionStorage.removeItem("ID Token");
navigate("/");
};
useEffect(() => {
setUserIdToken(sessionStorage.getItem("ID Token"));
}, []);
useEffect(() => {
if (userIdToken) {
const q = query(
collection(db, "messages"),
where("userIdToken", "==", userIdToken),
orderBy("createdAt"),
limit(50)
);
const unsubscribe = onSnapshot(q, (QuerySnapshot) => {
let messages = [];
QuerySnapshot.forEach((doc) => {
messages.push({ ...doc.data(), id: doc.id });
});
setMessages(messages);
});
return () => unsubscribe;
}
}, [userIdToken]);
const handleSendMessage = (data) => {
const user = auth.currentUser;
if (user) {
db.collection("messages").add({
...data,
name: user.displayName,
avatar: user.photoURL,
createdAt: new Date(),
userId: user.uid,
userIdToken: userIdToken,
});
setMessages([
...messages,
{
...data,
createdAt: new Date(),
userId: user.uid,
userIdToken: userIdToken,
},
]);
}
};
return (
<main className="chat-box">
<div className="messages-wrapper">
{messages.map((message) => (
<Chat key={message.id} message={message} />
))}
</div>
<span ref={scroll}></span>
<SendMessage scroll={scroll} onSendMessage={handleSendMessage} />
<button onClick={handleLogout}>Logout</button>
</main>
);
};
export default MainPage;
SendMessage.jsx:
import React, { useState } from "react";
import { auth, db } from "../components/base";
import { addDoc, collection, serverTimestamp } from "firebase/firestore";
const SendMessage = ({ scroll }) => {
const [message, setMessage] = useState("");
const sendMessage = async (event) => {
event.preventDefault();
if (message.trim() === "") {
alert("Enter valid message");
return;
}
const { uid, displayName, photoURL } = auth.currentUser;
await addDoc(collection(db, "messages"), {
text: message,
name: displayName,
avatar: photoURL,
createdAt: serverTimestamp(),
uid,
});
setMessage("");
scroll.current.scrollIntoView({ behavior: "smooth" });
};
return (
<form onSubmit={(event) => sendMessage(event)} className="send-message">
<label htmlFor="messageInput" hidden>
Enter Message
</label>
<input
style={{marginLeft: '100px'}}
id="messageInput"
name="messageInput"
type="text"
className="form-input__input"
placeholder="type message..."
value={message}
onChange={(e) => setMessage(e.target.value)}
/>
<button type="submit">Send</button>
</form>
);
};
export default SendMessage;
Chat.jsx:
Chat.jsx:import React from "react";
import './Chat.css';
const Chat = ({ message }) => {
const timestamp = new Date(message.createdAt).toLocaleString();
return (
<div>
<div className="chat-bubble__right">
<p className="user-name">{message.name}</p>
<p className="user-message">{message.text}</p>
<p className="timestamp">{new Date(message.createdAt).toLocaleString()}</p>
</div>
</div>
);
};
export default Chat;
Cloud Firestore rules:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read: if true;
allow write: if request.auth.uid != null;
}
}
}
Cloud Firestore indexes:
Collection ID Fields indexed
Query scope Status
messages userIdToken Ascending createdAt Ascending __name__ Ascending Collection Enabled
So when a user types a message, it should display on the website and store in Firestore Database, in my case, it only stores in Firestore.
I've no clue what causes this issue...

How to set authentication status with redux-toolkit and firebase using onAuthStateChanged? [duplicate]

This question already has an answer here:
How to use firebase authentication with Redux Toolkit using onAuthStateChanged?
(1 answer)
Closed 7 months ago.
I am trying to set the auth status for the currently logged-in user using redux-toolkit's createAsyncThunk and firebase's onAuthStatechanged, but I cannot do so. I am trying to implement a private route that can only be accessed if a user is logged in.
*What I have tried
I create an authService.js file where I created a function checkAuthStatus which calls onAuthStateChanged and returns a user if a user is there else null and then from authSlice, I have exported another function checkUserStatus which returns a promise, and when it gets fulfilled the user will be set to the user returned but the returned value is always null even if the user is logged in.
const checkAuthStatus = () => {
onAuthStateChanged(auth, (user) => {
console.log(user);
return user ? user : null;
});
};
const authService = {
registerUser,
loginUser,
checkAuthStatus,
};
export default authService;
export const checkUserStatus = createAsyncThunk('auth/checkAuth', () => {
return authService.checkAuthStatus();
});
.addCase(checkUserStatus.pending, (state, action) => {
state.isLoading = true;
})
.addCase(checkUserStatus.fulfilled, (state, action) => {
state.user = action.payload;
state.isLoading = false;
});
import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { Outlet, Navigate } from 'react-router-dom';
import { checkUserStatus } from './../features/auth/authSlice';
import Loader from './Loader';
const PrivateComponent = () => {
const { user, isLoading } = useSelector((state) => state.auth);
const dispatch = useDispatch();
useEffect(() => {
dispatch(checkUserStatus());
}, [dispatch]);
if (isLoading) {
return <Loader />;
}
return user ? <Outlet /> : <Navigate to="/login" />;
};
export default PrivateComponent;
Problem
I am not sure why but the function in the authSerice file checkAuthStatus is returning null even if the current user is not null. One more thing is that the user field from the state is not even there in the redux dev tools, check images for more.
Here is my code:-
authService.js authService Page Image
authSlice.js authSlice function || authSlice extrareducer
PrivateComponent.js Private Route component
App.js Routes for app
one more thing I have notice is the user state is not even there as redux dev tools are showing
this is pending
before
this is fulfilled
after
I have changed the code and now the auth is working but on refreshing the page the user status is user get redirected to login page why?
How to set authentication status with firebase using onAuthStateChanged ?
There are many way to achieve this:
Using global store
const userSlice = createSlice({
name: "users",
initialState,
reducers: {
setLoginStatus: (state, action) {
state.loginStatus = action.payload;
}
},
extraReducers: {
[createUser.fulfilled]: (state, action) => {
state.loginStatus = true;
},
[createUser.rejected]: (state, action) => {
state.loginStatus = false;
},
},
});
// trackUserAuth.ts
onAuthStateChanged(auth, (user) => {
if (user) {
store.dispatch(setLoginStatus(true))
} else {
store.dispatch(setLoginStatus(true))
}
});
Using hooks
export const useAuth = () => {
const dispatch = useDispatch();
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (user) => {
if (user) {
dispatch(setLoginStatus(true))
} else {
dispatch(setLoginStatus(true))
}
});
return unsubscribe;
}, []);
}
Using thunks
export const checkAuthStatus = () => (dispatch) {
const unsubscribe = Firebase.auth().onAuthStateChanged(user => {
if (user) {
dispatch(setLoginStatus(true))
} else {
dispatch(setLoginStatus(true))
}
});
return unsubscribe;
}

Uncaught (in promise) Error: Invalid hook call. Hooks can only be called inside of the body of a function component. - useEffect()

I get this error when I try and call a function I have imported within my useEffect() hook in Dashboard.jsx. I am just trying to pull in data from database on the page load pretty much so that when user click button they can send off correct credentials to the api.
I am pulling it in from database for security reasons, so client id is not baked into the code.
I am pretty sure that I am getting this error maybe because the function is not inside a react component? although I am not 100% sure. And if that is the case I am not sure of the best way to restructure my code and get the desired output.
Code below.
mavenlinkCredentials.js
import { doc, getDoc } from "firebase/firestore";
import { useContext } from "react";
import { AppContext } from "../../context/context";
import { db } from "../../firebase";
const GetMavenlinkClientId = async () => {
const {setMavenlinkClientId} = useContext(AppContext)
const mavenlinkRef = doc(db, 'mavenlink', 'application_id');
const mavenlinkDocSnap = await getDoc(mavenlinkRef)
if(mavenlinkDocSnap.exists()){
console.log("mavenlink id: ", mavenlinkDocSnap.data());
console.log(mavenlinkDocSnap.data()['mavenlinkAccessToken'])
setMavenlinkClientId(mavenlinkDocSnap.data()['application_id'])
} else {
console.log("No doc");
}
}
export default GetMavenlinkClientId;
Dashboard.jsx
import React, { useContext, useEffect, useState } from "react";
import { useAuthState } from "react-firebase-hooks/auth";
import { useNavigate } from "react-router-dom";
import { query, collection, getDocs, where, setDoc, doc, getDoc } from "firebase/firestore";
import { auth, db, logout } from "../firebase";
import { Button, Container, Grid, Paper } from "#mui/material";
import ListDividers from "../components/ListDividers";
import { AppContext } from "../context/context";
import axios from "axios";
import {SuccessSnackbar, ErrorSnackbar} from '../components/PopupSnackbar';
import GetMavenlinkClientId from "../helpers/firebase/mavenlinkCredentials";
const Dashboard = () => {
const [user, loading, error] = useAuthState(auth);
const [name, setName] = useState("");
const [ accessToken, setAccessToken ] = useState("")
const [errorAlert, setErrorAlert] = useState(false);
const [successAlert, setSuccessAlert] = useState(false);
const [mavenlinkClientId, setMavenlinkClientId] = useState("");
const {isAuthenticated} = useContext(AppContext);
const navigate = useNavigate();
const uid = user.uid
const parsedUrl = new URL(window.location.href)
const userTokenCode = parsedUrl.searchParams.get("code");
const { mavenlinkConnected, setMavenlinkConnected } = useContext(AppContext)
const { maconomyConnected, setMaconomyConnected } = useContext(AppContext)
const { bambooConnected, setBambooConnected } = useContext(AppContext)
const fetchUserName = async () => {
try {
const q = query(collection(db, "users"), where("uid", "==", user?.uid));
const doc = await getDocs(q);
const data = doc.docs[0].data();
setName(data.name);
} catch (err) {
console.error(err);
alert("An error occured while fetching user data");
}
};
//
useEffect(() => {
if (loading) return;
if (!user) return navigate("/");
fetchUserName();
if(userTokenCode !== null){
authorizeMavenlink();
}
if(isAuthenticated){
GetMavenlinkClientId()
}
}, [user, loading]);
///put this into a page load (use effect maybe) so user does not need to press button to connect to apis
const authorizeMavenlink = () => {
console.log(uid);
const userRef = doc(db, 'users', uid);
axios({
//swap out localhost and store in variable like apitool
method: 'post',
url: 'http://localhost:5000/oauth/mavenlink?code='+userTokenCode,
data: {}
})
.then((response) => {
setAccessToken(response.data);
setDoc(userRef, { mavenlinkAccessToken: response.data}, { merge: true });
setMavenlinkConnected(true);
setSuccessAlert(true);
})
.catch((error) => {
console.log(error);
setErrorAlert(true)
});
}
//abstract out client id and pull in from db
const getMavenlinkAuthorization = () => {
window.open('https://app.mavenlink.com/oauth/authorize?client_id='+mavenlinkClientId+'&response_type=code&redirect_uri=http://localhost:3000');
window.close();
}
const authorizeBamboo = () => {
axios({
method: 'get',
url: 'http://localhost:5000/oauth/bamboo',
data: {}
})
.then((response) => {
console.log(response)
})
.catch((error) => {
console.log(error);
});
// console.log('bamboo connected')
setBambooConnected(true);
}
const authorizeMaconomy = () => {
console.log("Maconomy connected")
setMaconomyConnected(true);
}
const syncAccount = async() => {
if(!mavenlinkConnected){
await getMavenlinkAuthorization()
}
if (!bambooConnected){
await authorizeBamboo();
}
if (!maconomyConnected){
await authorizeMaconomy();
}
}
const handleAlertClose = (event, reason) => {
if (reason === 'clickaway') {
return;
}
setSuccessAlert(false) && setErrorAlert(false);
};
console.log(mavenlinkClientId);
return(
<>
<Container>
<div className="dashboard">
<h1>Dashboard</h1>
<Grid container spacing={2}>
<Grid item xs={12}>
<Paper style={{paddingLeft: "120px", paddingRight: "120px"}} elevation={1}>
<div className="dashboard-welcome">
<h2>Welcome {name}</h2>
<h4>{user?.email}</h4>
<hr/>
<h2>Integrations</h2>
<Button onClick={syncAccount}>
Sync Account
</Button>
{/* <Button onClick={getMavenlinkClientId}>
Bamboo Test
</Button> */}
<ListDividers/>
</div>
</Paper>
</Grid>
</Grid>
</div>
{successAlert === true ? <SuccessSnackbar open={successAlert} handleClose={handleAlertClose}/> : <></> }
{errorAlert === true ? <ErrorSnackbar open={errorAlert} handleClose={handleAlertClose}/> : <></> }
</Container>
</>
);
}
export default Dashboard;
the error is because you’re calling const {setMavenlinkClientId} = useContext(AppContext) inside the file mavenlinkCredentials.js which is not a react components.
you could maybe change the function inside mavenlinkCredentials.js to accept a setMavenlinkClientId and pass it from outside like this.
const GetMavenlinkClientId = async (setMavenlinkClientId) => {
const mavenlinkRef = doc(db, 'mavenlink', 'application_id');
const mavenlinkDocSnap = await getDoc(mavenlinkRef)
if(mavenlinkDocSnap.exists()){
console.log("mavenlink id: ", mavenlinkDocSnap.data());
console.log(mavenlinkDocSnap.data()['mavenlinkAccessToken'])
setMavenlinkClientId(mavenlinkDocSnap.data()['application_id'])
} else {
console.log("No doc");
}
}
and then you can call this function in your dashboard.js like so,
const {setMavenlinkClientId} = useContext(AppContext)
if(isAuthenticated){
GetMavenlinkClientId(setMavenlinkClientId)
}

How to include username in firebase's 'createUserWithEmailAndPassword' authentication method

I'm trying to make a Username and Password Authentication in a web app that is made with react and firebase.
But I'm really new to firebase and I couldn't find any good documentation about the process, I have read about Firestore but I don't know how to connect it to the authentication method. Any help or hint is appreciated!
Here is the signup function of my /register route.
async function handleSubmit(e) {
e.preventDefault()
if (passwordRef.current.value !== passwordConfirmationRef.current.value){
return setError('Passwords do not match');
}
try {
setError('')
setLoading(true)
await signup(emailRef.current.value, passwordRef.current.value, usernameRef.current.value)
Home()
} catch {
setError('Failed to create an account')
}
setLoading(false)
}
And this is my 'AuthContext.JSX' code:
import React, { useContext , useEffect, useState } from 'react'
const AuthContext = React.createContext()
import {auth} from '../firebase'
export function useAuth() {
return useContext(AuthContext)
}
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState()
const [loading, setLoading] = useState(true)
function signup(email, password) {
return auth.createUserWithEmailAndPassword(email, password)
}
function login(email, password) {
return auth.signInWithEmailAndPassword(email, password)
}
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(user => {
setCurrentUser(user)
setLoading(false)
})
return unsubscribe
}, [])
auth.onAuthStateChanged(user => {
setCurrentUser(user)
})
const value = {
currentUser,
signup,
login
}
return (
<AuthContext.Provider value={value}>
{!loading && children }
</AuthContext.Provider>
)
}
Just to let you know the authentication is working well the only problem is getting the Display Name and exporting it to the home page for display.
I want to display the username on this page
Thanks to Dhamaraj I used the updateProfile() function inside my Register route, and it worked properly for adding a display name to the user which I used on the home page for the profile display.
That is the new function, may it helps somebody with the same issue:
async function handleSubmit(e) {
e.preventDefault()
if (passwordRef.current.value !== passwordConfirmationRef.current.value){
return setError('Passwords do not match');
}
try {
setError('')
setLoading(true)
await signup(emailRef.current.value, passwordRef.current.value)
auth.currentUser.updateProfile({
displayName: usernameRef.current.value
}).then(() => {
console.log('Username is: ' + auth.currentUser.displayName)
}).catch((error) => {
console.log('An error was occured while updating the profile.')
});
Home()
} catch {
setError('Failed to create an account')
}
setLoading(false)
}

REACT/REDUX Action not getting dispatched

What I am tying to do is when the user clicks on sign in button my action gets dispatch with email and password.
But, my action is not getting dispatched. Like when I checked my redux-dev-tools it is not showing anything:
There are no error message in console. I checked other answer's but nothing helped.
Here is the source code:
LoginScreen.js
import React, { useState, useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import ErrorMessage from "../../components/ErrorMessage/ErrorMessage";
import Loader from "../../components/Loader/Loader";
import { login } from "../../redux/actions/userActions";
import "./LoginScreen.scss";
const LoginScreen = ({ location, history }) => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const dispatch = useDispatch();
const userLogin = useSelector((state) => state.userLogin);
const { loading, error, userInfo } = userLogin;
const redirect = location.search ? location.search.split("=")[1] : "/";
useEffect(() => {
if (userInfo) {
history.push(redirect);
}
}, [history, userInfo, redirect]);
const submitHandler = (e) => {
e.preventDefault();
dispatch(login(email, password));
};
return (
<>
<div className="login-container">
<div className="login-form">
<h1>Login</h1>
{loading ? (
<Loader />
) : error ? (
<ErrorMessage error={error} />
) : (
<form onSubmit={submitHandler}>
<div className="login-form-items">
<input
className="login-input"
type="email"
placeholder="Email address"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<input
className="login-input"
type="password"
placeholder="Password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<button type="submit" value="submit">
Login
</button>
<h4>OR</h4>
<div className="login-form-social">
<button className="social">
<img
className="googleLogo"
src="/logo/google.svg"
alt="G"
/>{" "}
Login with Google
</button>
<button className="social social-github">
<img
className="githubLogo"
src="/logo/github.svg"
alt="GH"
/>{" "}
Login with GitHub
</button>
</div>
</div>
</form>
)}
</div>
</div>
</>
);
};
export default LoginScreen;
userAction.js
import axios from "axios";
import {
USER_LOGIN_FAIL,
USER_LOGIN_REQUEST,
USER_LOGIN_SUCCESS,
} from "../constants/userConstants";
export const login = () => (email, password) => async (dispatch) => {
try {
dispatch({
type: USER_LOGIN_REQUEST,
});
const config = {
headers: {
"Content-Type": "appllication/json",
},
};
const { data } = await axios.post(
"/api/users/login",
{ email, password },
config
);
dispatch({
type: USER_LOGIN_SUCCESS,
payload: data,
});
localStorage.setItem("userInfo", JSON.stringify(data));
} catch (error) {
dispatch({
type: USER_LOGIN_FAIL,
payload:
error.response && error.response.data.message
? error.response.data.message
: error.message,
});
}
};
userReducer.js
import {
USER_LOGIN_FAIL,
USER_LOGIN_REQUEST,
USER_LOGIN_SUCCESS,
USER_LOGOUT,
} from "../constants/userConstants";
export const userLoginReducer = (state = {}, action) => {
switch (action.type) {
case USER_LOGIN_REQUEST:
return { loading: true };
case USER_LOGIN_SUCCESS:
return { loading: false, userInfo: action.payload };
case USER_LOGIN_FAIL:
return { loading: false, error: action.payload };
case USER_LOGOUT:
return {};
default:
return state;
}
};
store.js
import { createStore, combineReducers, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import { composeWithDevTools } from "redux-devtools-extension";
// reducers
import { userLoginReducer } from "./reducers/userReducers";
const reducer = combineReducers({
userLogin: userLoginReducer,
});
const userInfoFromStorage = localStorage.getItem("userInfo")
? JSON.parse(localStorage.getItem("userInfo"))
: null;
const initialState = {
userLogin: { userInfo: userInfoFromStorage },
};
const middleware = [thunk];
const store = createStore(
reducer,
initialState,
composeWithDevTools(applyMiddleware(...middleware))
);
export default store;
You've defined your action wrong. With redux-thunk you define your actions like this:
export const login = (email, password) => async (dispatch) => {
// your action code
};
// The above code is equivalent to
export const login = (email, password) => {
return async (dispatch) => {
// your action code
}
}
Not like this:
export const login = () => (email, password) => async (dispatch) => {
// your action code
};
// The above code is equivalent to
export const login = () => {
return (email, password) => {
return async (dispatch) => { // this is wrong
}
}
}
So your action is returning a function which then returns another function.
The way you use it caught my attention. Out of general use. Generally, api operations are done with packages such as saga or thunk. Action is only used as a hyperlink. I suggest you review the article below. I think this build will solve your problem.
https://blog.devgenius.io/reactjs-simple-understanding-redux-with-redux-saga-f635e273e24a

Categories

Resources