1

I'm new to react, and I'm working on my biggest project yet, which is an online store. How original of me, I know.

I've created a context classes for the information I wish to pass on to other components:

import React from "react";

const AuthContext = React.createContext(
    {
        isLoggedIn: false,
        isLoggedInEditVal: ()=>{},
        currentLoggedUserId: "",
        edit_currentLoggedUserId: ()=> {},
    }
    
);

export default AuthContext;

and

import React from "react";

const usersAndProductsContext = React.createContext(
    {
        usersVal: [],
        productsVal: [],
        toggle_pressed_login_flag: () => {},
        handleAddUser: () => {}
    }
    
);

export default usersAndProductsContext;

In my App component, I wrap with both usersAndProductsContext.Provider and AuthContext.Provider, and pass in both of them the data I wish to share with my other components:

return (
    <div className="App">
    <usersAndProductsContext.Provider value={{
        usersVal: usersVal,
        productsVal: productsVal,
        toggle_pressed_login_flag: toggle_pressed_login_flag,
        handleAddUser: handleAddUser
    }}>
    <AuthContext.Provider
    value={{
      isLoggedIn: false,
      currentUserId: "",
      edit_currentLoggedUserId: edit_currentLoggedUserId,
      currentLoggedUserId: currentLoggedUserId,
    }}>
    <Routes>
        <Route exact path="/" element={<Login />}/>
        <Route exact path="farmers" element={<Farmers />}/>
        <Route exact path="customer" element={<Customer />}/>
        <Route exact path="register" element={<Register />}/>
        {/* <Route exact path="log%20in" element={<Login usersVal={usersVal}/>}/>  */}
    </Routes>
    </AuthContext.Provider>
    </usersAndProductsContext.Provider>
    </div>
  );
}

After making a login, I wish to redirect myself to another component at that point, while saving data.

My attempt doing it with useNavigate:

import * as React from 'react';
import Avatar from '@mui/material/Avatar';
import Button from '@mui/material/Button';
import CssBaseline from '@mui/material/CssBaseline';
import TextField from '@mui/material/TextField';
import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import Link from '@mui/material/Link';
import Grid from '@mui/material/Grid';
import Box from '@mui/material/Box';
import LockOutlinedIcon from '@mui/icons-material/LockOutlined';
import Typography from '@mui/material/Typography';
import Container from '@mui/material/Container';
import { createTheme, ThemeProvider } from '@mui/material/styles';
import logo_img from "../Images/logo.png";
import { useNavigate } from 'react-router-dom';
import { useState, useContext } from 'react';
import { Paper } from '@material-ui/core';
import ErrorPopup from '../Components/ErrorPopup';
import AuthContext from '../Contexts/isLoggedIn-context';
import usersAndProductsContext from '../Contexts/usersAndProducts-context';

function Copyright(props) {
    return (
        <Typography variant="body2" color="text.secondary" align="center" {...props}>
            {'Copyright © '}
            <Link color="inherit" href="http://localhost:3000">
                iFarm
            </Link>{' '}
            {new Date().getFullYear()}
            {'.'}
        </Typography>
    );
}

const theme = createTheme();

export default function Login() {
    let [is_wrongLoginFlag, edit_is_wrongLoginFlag] = useState(false);
    // let [loggedinVal, edit_loggedinVal] = useState(false);
    let navigate = useNavigate();
    //retrieve info from CONTEXES
    const authCtx = useContext(AuthContext);
    const usersAndItemsCtx = useContext(usersAndProductsContext)
    
    //our user array
    const usersVal = usersAndItemsCtx.usersVal
    // console.log("first" + usersVal[0].firstname)
    React.useEffect(()=> {
        {is_wrongLoginFlag ? setTimeout(()=>edit_is_wrongLoginFlag(false), 1000) : <></> }
        
    }, [is_wrongLoginFlag])

    //after inserting email and password, verify their existence.
    const handleSubmit = (event) => {
        event.preventDefault();
        const data = new FormData(event.currentTarget);
        let res = usersVal.find(user => user.email === data.get('email'));
        
        if (res != undefined && res.password === data.get('password')) {
            usersAndItemsCtx.toggle_pressed_login_flag(true); // need to verify this one.. 
            setTimeout(()=>{authCtx.edit_currentLoggedUserId(res.id)}, 1000)
            
            console.log("in login" + authCtx.currentLoggedUserId)

            // this email exists, progress to verifying pw.
            navigate('/farmers'); // as a logged in user
            // return (<></>)
        }
        else {
            edit_is_wrongLoginFlag(true);
        }
    };

    return (
        <ThemeProvider theme={theme}>
            <Container component="main" maxWidth="xs">
                <Paper sx={{ background: "linear-gradient(to right, #5433ff, #20bdff, #a5fecb)" }}>
                    <CssBaseline />
                    <Box
                        sx={{
                            marginTop: 8,
                            display: 'flex',
                            flexDirection: 'column',
                            alignItems: 'center',
                        }}
                    >
                        <Avatar sx={{ m: 1, bgcolor: 'secondary.main' }}>
                            <LockOutlinedIcon />
                        </Avatar>
                        <Typography component="h1" variant="h5">
                            Welcome back
                        </Typography>
                        <Box component="form" onSubmit={handleSubmit} noValidate sx={{ mt: 1 }}>
                            <TextField
                                margin="normal"
                                required
                                fullWidth
                                id="email"
                                label="Email Address"
                                name="email"
                                autoComplete="email"
                                autoFocus
                            />
                            <TextField
                                margin="normal"
                                required
                                fullWidth
                                name="password"
                                label="Password"
                                type="password"
                                id="password"
                                autoComplete="current-password"
                            />
                            <FormControlLabel
                                control={<Checkbox value="remember" color="primary" />}
                                label="Remember me"
                            />
                            <Button
                                type="submit"
                                fullWidth
                                variant="contained"
                                //   onClick={handleVerifyUserLogin}
                                sx={{ mt: 3, mb: 2 }}
                            >
                                Sign In
                            </Button>
                            
                            {is_wrongLoginFlag ? <ErrorPopup message={"wrong email or password (maybe even both)"}/> : <></> }

                            <Grid container>
                                <Grid item xs>
                                    <Link href="#" variant="body2">
                                        Forgot password?
                                    </Link>
                                </Grid>
                                <Grid item>
                                    <Link href="/register" variant="body2">
                                        {"Don't have an account? Sign Up"}
                                    </Link>
                                </Grid>
                            </Grid>
                        </Box>
                    </Box>
                    <Copyright sx={{ mt: 8, mb: 4 }} />
                </Paper>
            </Container>
        </ThemeProvider>
    );
}

It seems like after I do the login and I'm being redirected to the 'farmers' page, I seem to lose my access to the context which was passed from my App.

Any ideas on how to sort such an issue?

If any further information is required, I would happily supply it.

Regards!

dani_l_n
  • 376
  • 1
  • 11
  • What context values exactly are being lost? After authenticating and being redirected to `"/farmers"` what is the issue then? – Drew Reese Oct 13 '22 at 19:13
  • @DrewReese, you're like a programming angel? I think you have solved 50% of my stackoverflow questions. so, thanks in advance! in my Farmers page which I'm being redirected via "useNavigate" to from my login page, after successful verification. When I'm using the useNavigate, does my Farmer component, which in "App.js" was Provider with certain Context, still have access to the Context? If so, I'm having some syntactic issue, else, design issue. – dani_l_n Oct 14 '22 at 07:06
  • Something like `[object Object]` usually occurs when you call `.toString()` on an object. Can you share the `Farmers` component? Also, if possible, do you think you could create a *running* [codesandbox](https://codesandbox.io/) demo of your code that we could inspect live? – Drew Reese Oct 14 '22 at 07:16

1 Answers1

0

you didn't change the state of "isLoggedIn" attribute on the AuthContext, "isLoggedIn" is always "false".

authCtx.isLoggedIn = true;

Add this line of code on the "Login" component after a successful login. It is also very recommended to use an AuthGuard to protect your routes that requires authentication.

Good luck with your project.