状态落后于 useEffect

时间:2021-06-29 22:16:48

标签: reactjs typescript use-effect use-state

我知道有类似问题的帖子很少,但我不明白如何解决他们的问题,我不确定是不是国家的问题。

我有一个下拉菜单,根据下拉菜单中点击的日期,我正在渲染当天的事件。我正在调用 useEffect 内部的一个函数,它返回一个布尔数组并将其设置为状态,然后我映射到该状态,并根据真/假我渲染组件或空白空间。看起来像这样:

加载时,事件状态有 2 项,但 EventEmptyCells 为空。在我点击下拉菜单中的任意一天后,emptyEventCells 状态会得到一个它应该在加载时得到的值。每次下一次点击它都会获得以前的值。

import React, { useEffect, useState } from 'react'
import { Box, Flex } from '@chakra-ui/react'
import EventCell from 'components/schedule/events/EventCell'
import { Event } from 'components/schedule/events/EventFlex'
import { generateEmptyEventCells, calculateEventLength } from 'components/schedule/events/generateEmptyEventCells'
import { eventHours } from 'components/schedule/scheduleData'
import { scheduleData } from 'components/schedule/scheduleData'
interface Props {
    clickedDay: number
}

const MobileEventsFlex = ({ clickedDay }: Props) => {

    const [emptyEventCells, setEmptyEventCells] = useState<boolean[]>([])
    const [events, setEvents] = useState<Event[]>([])
    let counter = 0;

    useEffect(() => {
        setEvents(scheduleData[clickedDay].events)

        setEmptyEventCells(generateEmptyEventCells(events, eventHours))
    }, [clickedDay])


    return (
        <Flex flexDirection='column' w='277px' h='700px' ml='2'>
            {emptyEventCells.map((isEmpty: boolean, index) => (
                <React.Fragment key={`mobileflex${index}`}>
                    {isEmpty ? (
                        <Box h="60px"></Box>
                    ) : (
                        <EventCell
                            isMobile
                            size={`${calculateEventLength(events[counter].startTime, events[counter].endTime) * 60}`}
                            icon={events[counter].icon}
                            type={events[counter].type}
                            title={events[counter].title}
                            time={`${events[counter].startTime}h-${events[counter++].endTime}h`}
                        />
                    )}
                </React.Fragment>
            ))}
        </Flex>
    )
}

export default MobileEventsFlex
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

生成EmptyEventsCells文件:

import { Event } from 'components/schedule/events/EventFlex'

export const generateEmptyEventCells = (events: Event[], eventHours: number[]) => {
    let tempFlexItems: boolean[] = []
    let tempEventHours = [...eventHours]

    //FIXME: This needs refactoring
    events.forEach((event) => {
        tempEventHours.forEach((hour) => {
            if (hour < event.startTime) {
                tempFlexItems.push(true)
            }
            if (hour === event.startTime) {
                tempFlexItems.push(false)
                tempEventHours = tempEventHours.slice(tempEventHours.findIndex((hour) => hour === event.endTime))
            }
        })
    })

    return tempFlexItems
}
export const calculateEventLength = (startTime: number, endTime: number) => {
    return endTime - startTime
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.1/umd/react-dom.production.min.js"></script>

计划数据文件:

export const eventHours = [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
export const eventDays = [
    {
        id: 0,
        day: 'Day 1',
        weekDay: 'Monday',
        date: 'November 30th',
    },
    {
        id: 1,
        day: 'Day 2',
        weekDay: 'Monday',
        date: 'November 30th',
    },
    {
        id: 2,
        day: 'Day 3',
        weekDay: 'Monday',
        date: 'November 30th',
    },
    {
        id: 3,
        day: 'Day 4',
        weekDay: 'Monday',
        date: 'November 30th',
    },
    {
        id: 4,
        day: 'Day 5',
        weekDay: 'Monday',
        date: 'November 30th',
    },
]
export const scheduleData = [
    {
        weekDay: {
            title: 'Day 1',
            day: 'Monday',
            date: 'NOvemb 30th',
        },
        events: [
            {
                icon: '/images/icons/talk.png',
                type: 'Lecture',
                title: 'adsasd',
                startTime: 11,
                endTime: 14,
            },
            {
                icon: '/images/icons/talk.png',
                type: 'Lecture',
                title: 'adsasd',
                startTime: 15,
                endTime: 17,
            },
        ],
    },
    {
        weekDay: {
            title: 'Day 2',
            day: 'Monday',
            date: 'NOvemb 30th',
        },
        events: [
            {
                icon: '/images/icons/talk.png',
                type: 'Lecture',
                title: 'adsasd',
                startTime: 11,
                endTime: 14,
            },
            {
                icon: '/images/icons/talk.png',
                type: 'Lecture',
                title: 'adsasd',
                startTime: 18,
                endTime: 20,
            },
        ],
    },
    {
        weekDay: {
            title: 'Day 3',
            day: 'Monday',
            date: 'NOvemb 30th',
        },
        events: [
            {
                icon: '/images/icons/talk.png',
                type: 'Lecture',
                title: 'adsasd',
                startTime: 9,
                endTime: 12,
            },
            {
                icon: '/images/icons/talk.png',
                type: 'Lecture',
                title: 'adsasd',
                startTime: 14,
                endTime: 16,
            },
        ],
    },
    {
        weekDay: {
            title: 'Day 4',
            day: 'Monday',
            date: 'NOvemb 30th',
        },
        events: [
            {
                icon: '/images/icons/talk.png',
                type: 'Lecture',
                title: 'adsasd',
                startTime: 15,
                endTime: 17,
            },
            {
                icon: '/images/icons/talk.png',
                type: 'Lecture',
                title: 'adsasd',
                startTime: 18,
                endTime: 20,
            },
        ],
    },
    {
        weekDay: {
            title: 'Day 2',
            day: 'Monday',
            date: 'NOvemb 30th',
        },
        events: [
            {
                icon: '/images/icons/talk.png',
                type: 'Lecture',
                title: 'adsasd',
                startTime: 10,
                endTime: 14,
            },
            {
                icon: '/images/icons/talk.png',
                type: 'Lecture',
                title: 'adsasd',
                startTime: 15,
                endTime: 18,
            },
        ],
    },
]

0 个答案:

没有答案