我通过历史 (react-router-dom) 将状态传递给功能组件,但它说状态是 'null'

I am passing the state to a function component via history (react-router-dom) but it says the state is 'null'

我需要将状态值传递给不同的组件,我想在不同的组件中使用它。

对于同样的问题,我问了一个不同的 question,但它作为重复问题被关闭了,但是,我已经尝试了上一个问题中提到的所有问题。我不认为这是一个重复的问题。

这是第一个组件中的一些代码:

    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(() => {
        if (serverMessage) {
            console.log(serverMessage)
            setServerMessage(serverMessage)
            console.log(serverMessage)
        }
    }, [serverMessage])

我试图访问状态的第二个组件中的代码。

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

这是第一页的完整代码:

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(() => {
        if (serverMessage) {
            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

这是我在第二个组件中得到的输出:

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

无论我尝试什么,我都无法将状态传递给不同的组件。我遵循了这个 但没有解决我的问题。

如何访问状态值?为什么它会变成 null?

编辑:

在我像这样更改历史之后:

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

我得到以下输出:serverMessage 对象仍然是空的:

hash: ""
​
key: "vi016u6e"
​
pathname: "/session/verifyotp"
​
search: ""
​
state: Object { serverMessage: "" }

已编辑: 我的 handleFormSubmit 函数

    const handleFormSubmit = async (event) => {
        event.preventDefault()
        console.log(formData)
        let newValue
        try {
            const response = await axios.post(
                `http://localhost:4000/accounts/register`,
                formData
            )
            console.log(response)
            console.log(response.data)
            newValue = response.data
            setServerMessage(newValue)
        } catch (error) {
            console.log(error)
        }
        history('/session/verifyotp', {
            state: { serverMessage: serverMessage },
        })
    }
    useEffect(() => {
        if (serverMessage) {
            console.log(serverMessage)
            console.log(serverMessage)
            setServerMessage(serverMessage)
        }
    }, [serverMessage])

浏览器控制台错误:

对于 react-router v6.

,您需要像这样使用您的历史记录
history("/session/verifyotp", {
  state: { serverMessage: serverMessage },
});

勾选 Documentation。它接受 to 和 state 作为可选参数。

这是我的组件A

import {useNavigate} from 'react-router-dom';

const ComponentA = (props) => {
  const navigate = useNavigate();
  const toComponentB = () => {
    navigate("/componentB", { state: { id: 1, name: "sabaoon" } });
  };
  return (
    <button
      onClick={() => {
        toComponentB();
      }}
    >
      Component B
    </button>
  );
};

export default ComponentA;

可以这样获取componentB中的状态数据

import { useLocation } from "react-router-dom";

function ComponentB() {
  const location = useLocation();
  return <div>{location?.state?.name}</div>;
}

export default ComponentB;

您可以像这样更新您的 handleFormSubmit 方法。您同时使用了 async/await.then,这让用户感到困惑。

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