javascript - 如何在使用 useEffect 和 setState 时有条件地呈现某些数据?
问题描述
我有一个父组件 EventPage 和一个子组件 UpcomingEvent。在 UpcomngEvent 组件中,我有我的 useEffect (不确定它是否应该存在或在 EventPage 组件中。我想要做的是:如果有即将发生的事件,我希望呈现某个代码部分,如果即将发生的事件为 null 我想渲染一段不同的代码。这是 UpcomingEvent 的代码:
import React, { useEffect, useState } from 'react'
import UpcomingShowFlyerDesktop from 'assets/images/flyer-desktop.png'
import UpcomingShowFlyerMobile from 'assets/images/flyer-mobile.png'
import { Grid } from '@material-ui/core'
import useStyles from '../styles'
function UpcomingEvent({ title, date, location, about }) {
const classes = useStyles()
const [upcomingEvent, setUpcomingEvent] = useState(null)
useEffect(() => {
setUpcomingEvent(
(upcomingEvent) =>
({
...upcomingEvent,
title: title,
date: date,
location: location,
about: about,
}[title][date][location][about])
)
})
return (
<div>
<div className={classes.upcomingShowsMobile}>
<div className={classes.titleContainerMobile}>
<p className={classes.upcomingShowTitleMobile}>
{title}
</p>
</div>
<div className={classes.dateLocationContainerMobile}>
<p className={classes.upcomingShowDateLocationMobile}>
{date} | {location}
</p>
</div>
<div className={classes.aboutContainerMobile}>
<p className={classes.aboutUpcomingShowMobile}>
{about}
</p>
</div>
<div className={classes.upcomingShowButtonContainerMobile}>
<button className={classes.upcomingShowButtonMobile}>
BUY TICKETS
</button>
</div>
</div>
这是父组件EventPage:
const EventsPage = () => {
const classes = useStyles()
const [events, setEvents] = useState(EVENTS)
// const startDate = '04/23/2021'
// const endDate = '05/04/2021'
return (
<div>
{/*-------------Mobile View--------------------- */}
<Grid
container
direction='column'
justify='center'
alignItems='center'
spacing={0}
className={classes.allContainerMobile}
>
<div className={classes.headingContainerMobile}>
<div>
<p className={classes.allEventsTitleMobile}>ALL EVENTS</p>
</div>
{UpcomingEvent === null ? (
<div>
<div className={classes.parentDivImageMobile}>
<div className={classes.ImageDivMobile}>
<img
src={EventsHeroImageMobile}
className={classes.placeHolderImageMobile}
/>
</div>
</div>
</div>
) : (
<div>
<Grid item sm={12} className={classes.gridMobile}>
<div className={classes.countdownContainerMobile}>
<div className={classes.countdownParentMobile}>
<CountdownTimer
countdown={startDate}
unixEndDate={endDate}
/>
</div>
</div>
</Grid>
</div>
)}
{UpcomingEvent === null ? (
<div>
<div>
<p className={classes.upcomingShowMobile}>UPCOMING SHOW</p>
</div>
<div>
<p className={classes.noUpcomingShowsMobile}>
NO UPCOMING SHOWS...FOR NOW.
</p>
</div>
</div>
) : (
<div>
<div className={classes.flyerImageMobile}>
<div className={classes.upcomingShowParentMobile}>
<img
src={UpcomingShowFlyerMobile}
className={classes.imageStyleMobile}
/>
</div>
</div>
</div>
)}
</div>
{UpcomingEvent !== null ? (
<div>
<UpcomingEvent
title={title}
date={date}
location={location}
about={about}
/>
</div>
) : null}
{UpcomingEvent === null ? (
<div>
<h2 className={classes.pastShowsMobile}>PAST SHOWS</h2>
</div>
) : (
<div>
<h2 className={classes.pastShowsUpcomingMobile}>PAST SHOWS</h2>
</div>
)}
<div className={classes.eventsCardMobile}>
{events.map(({ month, day, title, time, location }, i) => (
<BasicCard
key={`${title}-${i}`}
month={month}
day={day}
title={title}
time={time}
location={location}
/>
))}
</div>
</Grid>
解决方案
我把我的 useEffect 钩子放在了错误的地方,并且使用了错误的标准。经过一番努力,我终于找到了答案(在留下评论的人的帮助下。这是新的和改进的 EventsPage:
import React, { useEffect, useState } from 'react'
import BasicCard from 'pages/EventsPage/EventsCard/index'
import UpcomingEvent from 'pages/EventsPage/UpcomingEvent/UpcomingEvent'
import UpcomingShowFlyerMobile from 'assets/images/flyer-mobile.png'
import EventsHeroImage from 'assets/images/events-hero-image.jpg'
import EventsHeroImageMobile from 'assets/images/events-mobile-hero-image.jpeg'
import CountdownTimer from 'pages/EventsPage/CountdownTimer/CountdownTimer'
import { Grid } from '@material-ui/core'
import useStyles from './styles'
const EVENTS = [
{
month: 'AUG',
day: '09',
title: 'SUMMER 2019 SHOWCASE',
time: '7:30PM-9:00PM',
location: 'The Irenic, San Diego, CA',
},
{
month: 'APR',
day: '17',
title: 'SPRING 2019 SHOWCASE',
time: '7:30PM-9:00PM',
location: 'The Irenic, San Diego, CA',
},
{
month: 'AUG',
day: '09',
title: 'FALL 2019 SHOWCASE',
time: '7:30PM-9:00PM',
location: 'The Irenic, San Diego, CA',
},
{
month: 'APR',
day: '17',
title: 'WINTER 2019 SHOWCASE',
time: '7:30PM-9:00PM',
location: 'The Irenic, San Diego, CA',
},
]
const UPCOMINGEVENT = [
{
title: 'WINTER 2020 SHOWCASE',
date: 'JAN 24TH',
location: 'THE IRENIC, SAN DIEGO',
about:
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Consectetur cursus nunc faucibus justo enim, eget dignissim lacus turpis. Tincidunt sed mauris in volutpat. Sapien fringilla libero, facilisis elementum nisi lobortis amet porttitor. Velit risus diam sit feugiat velit enim et, euismod quis.',
},
]
// const UPCOMINGEVENT = [
// {
// title: null,
// date: null,
// location: null,
// about: null,
// },
// ]
const EventsPage = () => {
const classes = useStyles()
const [events, setEvents] = useState(EVENTS)
const [upcomingEvent, setUpcomingEvent] = useState(UPCOMINGEVENT)
useEffect(() => {
if (upcomingEvent !== null) {
setUpcomingEvent(UPCOMINGEVENT)
} else {
null
}
}, [upcomingEvent])
const startDate = '04/23/2021'
const endDate = '05/04/2021'
return (
<div>
{/*-------------Mobile View--------------------- */}
<Grid
container
direction='column'
justify='center'
alignItems='center'
spacing={0}
className={classes.allContainerMobile}
>
<div className={classes.headingContainerMobile}>
<div>
<p className={classes.allEventsTitleMobile}>ALL EVENTS</p>
</div>
{upcomingEvent === null ? (
<div>
<div className={classes.parentDivImageMobile}>
<div className={classes.ImageDivMobile}>
<img
src={EventsHeroImageMobile}
className={classes.placeHolderImageMobile}
/>
</div>
</div>
</div>
) : (
<div>
<Grid item sm={12} className={classes.gridMobile}>
<div className={classes.countdownContainerMobile}>
<div className={classes.countdownParentMobile}>
<CountdownTimer
countdown={startDate}
unixEndDate={endDate}
/>
</div>
</div>
</Grid>
</div>
)}
{upcomingEvent === null ? (
<div>
<div>
<p className={classes.upcomingShowMobile}>UPCOMING SHOW</p>
</div>
<div>
<p className={classes.noUpcomingShowsMobile}>
NO UPCOMING SHOWS...FOR NOW.
</p>
</div>
</div>
) : (
<div>
<div className={classes.flyerImageMobile}>
<div className={classes.upcomingShowParentMobile}>
<img
src={UpcomingShowFlyerMobile}
className={classes.imageStyleMobile}
/>
</div>
</div>
</div>
)}
</div>
{upcomingEvent !== null ? (
<div>
{upcomingEvent.map(({ title, date, location, about }) => (
<UpcomingEvent
key={title}
title={title}
date={date}
location={location}
about={about}
/>
))}
</div>
) : null}
{upcomingEvent === null ? (
<div>
<h2 className={classes.pastShowsMobile}>PAST SHOWS</h2>
</div>
) : (
<div>
<h2 className={classes.pastShowsUpcomingMobile}>PAST SHOWS</h2>
</div>
)}
<div className={classes.eventsCardMobile}>
{events.map(({ month, day, title, time, location }, i) => (
<BasicCard
key={`${title}-${i}`}
month={month}
day={day}
title={title}
time={time}
location={location}
/>
))}
</div>
</Grid>
这是 UpcomingEvent 组件:
import UpcomingShowFlyerDesktop from 'assets/images/flyer-desktop.png'
import { Grid } from '@material-ui/core'
import useStyles from '../styles'
function UpcomingEvent({ title, date, location, about }) {
const classes = useStyles()
return (
<div>
<div className={classes.upcomingShowsMobile}>
<div className={classes.titleContainerMobile}>
<p className={classes.upcomingShowTitleMobile}>{title}</p>
</div>
<div className={classes.dateLocationContainerMobile}>
<p className={classes.upcomingShowDateLocationMobile}>
{date} | {location}
</p>
</div>
<div className={classes.aboutContainerMobile}>
<p className={classes.aboutUpcomingShowMobile}>{about}</p>
</div>
<div className={classes.upcomingShowButtonContainerMobile}>
<button className={classes.upcomingShowButtonMobile}>
BUY TICKETS
</button>
</div>
</div>
</div>
)
}
export default UpcomingEvent
推荐阅读
- javascript - 纯 JavaScript 淡出然后加载
- asp.net-mvc - ASP.NET Core MVC 中的 Web 应用程序
- python - 根据另一个列表中的值从元组列表中删除重复值
- java - 我应该使用 System.out 或 Log4j 来打印普通信息吗?
- c# - XML 反序列化 System.InvalidOperationException”
没想到 - javascript - 刷新后如何保持状态
- javascript - 如何在 Node.js/Jest 中模拟嵌套模块响应
- r - 如何在r中读取列表列表
- python - 当 python 客户端在烧瓶中使用时,Grpc 请求失败
- c# - ASP.NET Web API 堆栈跟踪不可用 - UseProblemDetails