我通过历史 (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',
}}
>
Sign in
</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 },
});
};
我需要将状态值传递给不同的组件,我想在不同的组件中使用它。
对于同样的问题,我问了一个不同的 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',
}}
>
Sign in
</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 },
});
};