0

I need to pass the state value to a different component and I want to use it in the different component.

Code in the first component:

    const handleFormSubmit = async (event) => {
        event.preventDefault()
        console.log(formData)
        try {
            await axios
                .post(`http://localhost:4000/accounts/register`, formData)
                .then(function (response) {
                    console.log(response)
                    console.log(response.data)
                    setServerMessage(response.data)
                })
        } catch (error) {
            console.log(error)
        }
        history({
            pathname: '/session/verifyotp',
            state: { serverMessage: serverMessage.message },
        })
    }

The second component where I am trying to access the state.

    const navigate = useNavigate()
    let data = useLocation()
    console.log(data)

I have tried to log the current state value in the console using this:

    useEffect(() => {
        console.log(serverMessage)
    }, [serverMessage])

I have tried to set the state in useffect like this:

    useEffect(() => {
        setServerMessage(serverMessage)
    }, [serverMessage])

The output I am getting in the browser console is:

Object { pathname: "/session/verifyotp", search: "", hash: "", state: null, key: "n1jhatdj" }

This is the complete code in the page :

import React, { useEffect, useState } from 'react'
import { Box, styled } from '@mui/system'
import { Grid, Button } from '@mui/material'
import { ValidatorForm, TextValidator } from 'react-material-ui-form-validator'
import Typography from '@mui/material/Typography'
import { FormLabel } from '@mui/material'
import Link from '@mui/material/Link'
import axios from 'axios'
import Appbar from '../Appbar'
import Alert from '@mui/material/Alert'
import Snackbar from '@mui/material/Snackbar'
import { useNavigate } from 'react-router-dom'

const FlexBox = styled(Box)(() => ({
    display: 'flex',
    alignItems: 'center',
}))

const JustifyBox = styled(FlexBox)(() => ({
    justifyContent: 'center',
}))

const IMG = styled('img')(() => ({
    width: '100%',
}))

const JWTRegister = styled(JustifyBox)(() => ({
    background: '#ffffff',
    minHeight: '100vh !important',
    input: {
        background: 'white',
        borderRadius: 25,
    },
}))

const JwtRegister = (props) => {
    const [serverMessage, setServerMessage] = useState('')
    const [open, setOpen] = useState(false)
    const history = useNavigate()

    const [formData, setFormData] = useState({
        name: '',
        mobile: '',
        email: '',
        password: '',
    })

    const handleClick = () => {
        setOpen(true)
    }

    const handleClose = (event, reason) => {
        if (reason === 'clickaway') {
            return
        }

        setOpen(false)
    }
    const { name, mobile, email, password } = formData

    const handleChange = (event) => {
        setFormData({
            ...formData,
            [event.target.name]: event.target.value,
        })
    }

    const handleFormSubmit = async (event) => {
        event.preventDefault()
        console.log(formData)
        try {
            await axios
                .post(`http://localhost:4000/accounts/register`, formData)
                .then(function (response) {
                    console.log(response)
                    console.log(response.data)
                    const newValue = response.data
                    setServerMessage(newValue)
                })
        } catch (error) {
            console.log(error)
        }
        history({
            pathname: '/session/verifyotp',
            state: { serverMessage: serverMessage },
        })
    }
    useEffect(() => {
        console.log(serverMessage)
        setServerMessage(serverMessage)
        console.log(serverMessage)
    }, [serverMessage])
    return (
        <JWTRegister>
            <Grid container>
                <Appbar />
                <Grid
                    pt={0}
                    pl={10}
                    pr={10}
                    item
                    lg={6}
                    md={6}
                    sm={6}
                    xs={12}
                    sx={{ height: '100vh', backgroundColor: '#3E8BFF' }}
                >
                    <Typography
                        component="h1"
                        variant="h3"
                        sx={{ textTransform: 'none', color: '#000' }}
                    >
                        Sign up
                    </Typography>
                    <Typography component="h1" variant="h5">
                        Register now to get 100 free credits
                    </Typography>
                    {serverMessage ? (
                        <>
                            <Alert
                                variant="filled"
                                autohideduration={6000}
                                severity="success"
                            >
                                {serverMessage.message}
                            </Alert>
                            <Snackbar
                                open={open}
                                autoHideDuration={3000}
                                onClose={handleClose}
                            >
                                <Alert
                                    onClose={handleClose}
                                    severity="success"
                                    sx={{ width: '100%' }}
                                >
                                    {serverMessage.message}
                                </Alert>
                            </Snackbar>
                        </>
                    ) : null}
                    <ValidatorForm id="Register" onSubmit={handleFormSubmit}>
                        <Grid container spacing={2}>
                            <Grid
                                item
                                lg={6}
                                md={6}
                                sm={12}
                                xs={12}
                                sx={{ mt: 2 }}
                            >
                                <FormLabel sx={{ color: '#000000' }}>
                                    Name
                                </FormLabel>
                                <TextValidator
                                    sx={{ mb: 3, width: '100%' }}
                                    size="small"
                                    type="text"
                                    name="name"
                                    value={name}
                                    autoFocus
                                    onChange={handleChange}
                                    validators={['required']}
                                    errorMessages={['Name field is required']}
                                    inputProps={{
                                        style: {
                                            borderRadius: 25,
                                            backgroundColor: 'white',
                                            disableUnderline: true,
                                        },
                                    }}
                                />
                            </Grid>
                            <Grid
                                item
                                lg={6}
                                md={6}
                                sm={12}
                                xs={12}
                                sx={{ mt: 2 }}
                            >
                                <FormLabel sx={{ color: '#000000' }}>
                                    Mobile
                                </FormLabel>
                                <TextValidator
                                    sx={{ mb: 3, width: '100%' }}
                                    size="small"
                                    type="text"
                                    name="mobile"
                                    value={mobile}
                                    onChange={handleChange}
                                    validators={['required']}
                                    errorMessages={[
                                        'Mobile Number field is required',
                                    ]}
                                    inputProps={{
                                        style: {
                                            borderRadius: 25,
                                            backgroundColor: 'white',
                                            disableUnderline: true,
                                        },
                                    }}
                                />
                            </Grid>
                        </Grid>
                        <FormLabel sx={{ color: '#000000' }}>Email</FormLabel>
                        <TextValidator
                            sx={{ mb: 3, width: '100%' }}
                            size="small"
                            type="email"
                            name="email"
                            value={email}
                            onChange={handleChange}
                            validators={['required', 'isEmail']}
                            inputProps={{
                                style: {
                                    borderRadius: 25,
                                    backgroundColor: 'white',
                                    disableUnderline: true,
                                },
                            }}
                            errorMessages={[
                                'Email field is required',
                                'Email is not valid',
                            ]}
                        />
                        <FormLabel sx={{ color: '#000000' }}>
                            Password
                        </FormLabel>
                        <TextValidator
                            sx={{ mb: '16px', width: '100%' }}
                            size="small"
                            name="password"
                            type="password"
                            value={password}
                            onChange={handleChange}
                            validators={['required']}
                            errorMessages={['Password field is required']}
                            inputProps={{
                                style: {
                                    borderRadius: 25,
                                    disableUnderline: true,
                                    backgroundColor: 'white',
                                },
                            }}
                        />
                        <FlexBox pb={2}>
                            <Button
                                type="submit"
                                variant="contained"
                                sx={{
                                    borderRadius: 25,
                                    textTransform: 'none',
                                    background: '#C7FF80',
                                    color: '#000000',
                                }}
                                onClick={handleClick}
                            >
                                Verify OTP
                            </Button>
                        </FlexBox>
                    </ValidatorForm>
                    <Typography
                        variant="subtitle1"
                        display="inline"
                        sx={{
                            textTransform: 'none',
                            color: '#000000',
                        }}
                    >
                        Already a member?
                        <Link
                            href="/session/signin"
                            sx={{
                                textTransform: 'none',
                                color: '#FFFFFF',
                            }}
                        >
                            &nbsp; Sign in &nbsp;
                        </Link>
                        instead.
                    </Typography>
                </Grid>
                <Grid
                    pt={1}
                    pl={10}
                    item
                    lg={6}
                    md={6}
                    sm={6}
                    xs={12}
                    sx={{ height: '100vh', backgroundColor: '#3E8BFF' }}
                >
                    <Typography pb={3} variant="body">
                        or sign up with
                    </Typography>
                    <Grid
                        pb={3}
                        pt={3}
                        container
                        alignItems="center"
                        spacing={2}
                    >
                        <Grid item>
                            <IMG
                                src="/assets/images/signup-linkedin.svg"
                                height={55}
                                width={55}
                            />
                        </Grid>
                        <Grid item>
                            <Typography pb={1} component="h6" variant="h6">
                                Linkedin
                            </Typography>
                        </Grid>
                    </Grid>
                    <Grid pb={3} container alignItems="center" spacing={2}>
                        <Grid item>
                            <IMG
                                src="/assets/images/signup-google.svg"
                                height={55}
                                width={55}
                            />
                        </Grid>
                        <Grid item>
                            <Typography pb={1} component="h6" variant="h6">
                                Google
                            </Typography>
                        </Grid>
                    </Grid>
                    <Grid pb={3} container alignItems="center" spacing={2}>
                        <Grid item>
                            <IMG
                                src="/assets/images/signup-facebook.svg"
                                height={55}
                                width={55}
                            />
                        </Grid>
                        <Grid item>
                            <Typography pb={1} component="h6" variant="h6">
                                Facebook
                            </Typography>
                        </Grid>
                    </Grid>
                    <Grid pb={3} container alignItems="center" spacing={2}>
                        <Grid item>
                            <IMG
                                src="/assets/images/signup-email.svg"
                                height={55}
                                width={55}
                            />
                        </Grid>
                        <Grid item>
                            <Typography component="h6" variant="h6">
                                Corporate Email ID
                            </Typography>
                            <span pb={1} component="h6" variant="h6">
                                (Use only Business email)
                            </span>
                        </Grid>
                    </Grid>
                </Grid>
            </Grid>
        </JWTRegister>
    )
}

export default JwtRegister

No matter what I try I am not able to pass the state to the different component. I have followed this question but does not solve my problem.

How can I access the state value? Why is it coming as null?

JustAG33K
  • 1,403
  • 3
  • 13
  • 28
  • 1
    The duplicate talks about `console.log` but just replace that with `history` and you have the same problem. You're using the closed over `serverMessage` variable with the old state, not the value you *just* assigned with `setServerMessage`. – Quentin Apr 12 '22 at 06:58
  • 1
    They are called [Function Components](https://reactjs.org/docs/components-and-props.html#function-and-class-components). They are (generally) not [functional](https://en.wikipedia.org/wiki/Functional_programming). – Quentin Apr 12 '22 at 06:59
  • I have updated the question and I have also followed the said question, however I am still not able to pass the state to the new component. – JustAG33K Apr 12 '22 at 10:30
  • "I have tried to log the current state value in the console using this:" — And what happens? Does it log the value you expect? – Quentin Apr 12 '22 at 10:31
  • "I have tried to set the state in useffect like this:" — That doesn't make sense. It just tries to recursively change the state every time the state changes. – Quentin Apr 12 '22 at 10:31
  • You're still trying to use `history` to navigate with the old value, so I would expect the app to navigate away from the component before any effects depending on the change of state triggered. – Quentin Apr 12 '22 at 10:32
  • When I log the current state value in the console. It does log the value as expected. – JustAG33K Apr 12 '22 at 10:32
  • "It does log the value as expected" — So you have a place in your code where you have the value you want. Use it to do what you want to do. As I said in my initial comment: The duplicate talks about console.log but just replace that with history – Quentin Apr 12 '22 at 10:33
  • When I place the history inside the useEffect like this: useEffect(() => { console.log(serverMessage) setServerMessage(serverMessage) console.log(serverMessage) history({ pathname: '/session/verifyotp', state: { serverMessage: serverMessage }, }) }, [serverMessage]) as soon as I start typing in the form the page redirect to the new component/page, without waiting for me to fill the form and clicking the submit button. – JustAG33K Apr 12 '22 at 10:36
  • Then your `serverMessage` variable seems to be being set both by typing and by getting an Ajax response, which doesn't really make a lot of sense. – Quentin Apr 12 '22 at 10:37
  • Thanks for trying to help me. useEffect(() => { console.log(serverMessage) setServerMessage(serverMessage) history({ pathname: '/session/verifyotp', state: { serverMessage: serverMessage }, }) console.log(serverMessage) }, [serverMessage, history]) When I have this code and I refresh the page the page redirects to the second component without even loading the first component. this is so weird. – JustAG33K Apr 12 '22 at 10:46
  • The effect runs the first time the component renders. If you don't want to do something then you need to test teh value of serverMessage to make sure it hasn't been defined yet (adjust for whatever the default value of serverMessage is) – Quentin Apr 12 '22 at 10:47
  • What i have done now is. I am logging the value of the serverMessage inside the effect to see the output. like this: useEffect(() => { console.log(serverMessage) setServerMessage(serverMessage) console.log(serverMessage) }, [serverMessage]) I get the following value with the correct line numbers in the console: message: "Registration successful, please check your email for verification instructions" – JustAG33K Apr 12 '22 at 10:51
  • I have updated the question with the complete code of the component. – JustAG33K Apr 12 '22 at 10:55
  • Hi @Quentin, I have updated the question with the complete code of the component. Can you look at the code? let me know what is mistake, that I am making. – JustAG33K Apr 12 '22 at 11:23

1 Answers1

0

I have found the answer to this question. react-router v6 In You need to use your history like this for react-router v6.

This is not the right way to pass state:

        history({
            pathname: '/session/verifyotp',
            state: { serverMessage: serverMessage.message },
        })

Correct way to pass state in react-router v6 is the following:

history("/session/verifyotp", {
  state: { serverMessage: serverMessage },
});
JustAG33K
  • 1,403
  • 3
  • 13
  • 28