I am trying to change the button based on if a user is logged in or not. the functionality is managed from MyNav.js. if the user is logged in I show the sign-out button, otherwise, I show the sign-in and sign-up button. It would be great if you can guide what part I am doing wrong.
Warning:
Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
at LoginSigninModal (http://localhost:3000/static/js/main.chunk.js:530:81)
at MenuButtons
MyNav.js
import React, { useEffect, useState } from 'react'
import Nav from 'react-bootstrap/Nav'
import Navbar from 'react-bootstrap/Navbar'
// import NavDropdown from 'react-bootstrap/NavDropdown'
import { Link } from 'react-router-dom'
import Searchfield from '../product_search_components/Searchfield'
import LoginSignout from '../login_components/LoginSignout'
import MenuButtons from './MenuButtons'
export default function MyNav(props) {
var isSigned
if (localStorage.getItem('scs_user_logged_in')){
isSigned = true
}else{
isSigned = false
}
const [signedIn, setSignedIn] = useState(isSigned)
var menu
if (signedIn) {
menu = <LoginSignout setSignedIn={setSignedIn}/>
} else {
menu = <MenuButtons setSignedIn={setSignedIn}/>
}
useEffect(()=>{
},[signedIn])
return (
<Navbar bg="light" expand="lg">
<Navbar.Brand><span style={{ fontWeight: 'bold' }}>Test</span></Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="mr-auto">
<Link className='nav-link' to="/">Home</Link>
<Link className='nav-link' to="/about">About</Link>
<Link className='nav-link' to="/todo">Todo</Link>
{/* <NavDropdown title="Dropdown" id="basic-nav-dropdown">
<NavDropdown.Item>Action</NavDropdown.Item>
<NavDropdown.Item>Another action</NavDropdown.Item>
<NavDropdown.Item>Something</NavDropdown.Item>
<NavDropdown.Divider />
<NavDropdown.Item>Separated link</NavDropdown.Item>
</NavDropdown> */}
</Nav>
</Navbar.Collapse>
<Searchfield search_item={props.search_item} setSearchItem={props.setSearchItem} />
{menu}
</Navbar>
)
}
MenuButtons.js
import LoginSigninModal from '../login_components/LoginSigninModal'
import LoginSignupModal from '../login_components/LoginSignupModal'
export default function MenuButtons(props) {
return (
<>
<LoginSigninModal {...props}/>
<LoginSignupModal />
</>
)
}
LoginSigninModal.js
import React, { useState, useEffect } from 'react'
import Button from 'react-bootstrap/Button'
import Modal from 'react-bootstrap/Modal'
import Form from 'react-bootstrap/Form'
import Alert from 'react-bootstrap/Alert'
import Spinner from 'react-bootstrap/Spinner'
import { baseURL } from './../assets/axiosInstance'
import axios from 'axios'
// import LoginSignupModal from './LoginSignupModal'
export default function LoginSigninModal(props) {
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
const [localSigned, setLocalSigned] = useState(false)
const [email, setEmail] = useState("")
const [password, setPassword] = useState("")
const errorEmail = false
const [apiCalling, setApiCalling] = useState(false)
const [messageOnSubmit, setMessageOnSubmit] = useState({
type: "",
message: ""
})
useEffect(() => {
props.setSignedIn(localSigned)
}, [localSigned, props])
function handleSubmit() {
setApiCalling(true)
const getData = async () => {
await axios.post(baseURL + 'auth/login', {
email: email,
password: password,
})
.then((response) => {
localStorage.setItem('scs_token', response.data['access_token'])
localStorage.setItem('scs_user', JSON.stringify(response.data['user']))
localStorage.setItem('scs_user_logged_in', true)
setLocalSigned(true)
setMessageOnSubmit({
type: "success",
message: "Login Successful"
})
})
.catch((error) => {
console.log(error.response.status)
if(error.response.status === 401){
setMessageOnSubmit({
type: "danger",
message: "Login failed due to wrong password."
})
}else if(error.response.status === 422){
setMessageOnSubmit({
type: "danger",
message: "Password needs to be at least 6 characters long."
})
}
})
.then(()=>{
setApiCalling(false)
})
}
getData()
}
return (
<>
<Button variant="primary" onClick={handleShow} style={{ marginLeft: '5px' }}>
Signin
</Button>
<Modal
show={show}
onHide={handleClose}
backdrop="static"
keyboard={false}
>
<Modal.Header closeButton>
<Modal.Title>Signin</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form>
<Form.Group controlId="formBasicEmail">
<Form.Label>Email address</Form.Label>
<Form.Control value={email} onChange={(data) => setEmail(data.target.value)} type="email" placeholder="[email protected]" />
</Form.Group>
<Form.Group controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control value={password} onChange={(data) => setPassword(data.target.value)} type="password" placeholder="Password" />
</Form.Group>
{(
messageOnSubmit['type'] !== ""
?
<Alert variant={messageOnSubmit['type']}>
{messageOnSubmit['message']}
</Alert>
:
"")}
<Button variant="primary" type="button" disabled={errorEmail} active={!errorEmail} onClick={handleSubmit}>Login {apiCalling && <Spinner animation="border" size="sm" />}</Button>
<Button variant="secondary" onClick={handleClose} style={{ marginLeft: "5px" }}>Close</Button>
</Form>
</Modal.Body>
<Modal.Footer>
</Modal.Footer>
</Modal>
</>
);
}
http://localhost:3000/static/js/main.chunk.js:530:81 - (from the warning message)
function LoginSigninModal(props) {
_s();
const [show, setShow] = Object(react__WEBPACK_IMPORTED_MODULE_1__["useState"])(--error marked here--)(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
question from:
https://stackoverflow.com/questions/66064885/cancel-all-subscriptions-and-asynchronous-tasks-in-a-useeffect-cleanup-function