首页 > 解决方案 > 三元运算符不返回反应组件

问题描述

我不太确定这个问题,所以我会更广泛地解释它。

我正在尝试制作反应计划组件,如下图所示:反应时间表

我得到的问题是我得到了没有元素的空弹性组件。

所以我有一个包含数据的 JSON 文件。它看起来像这样:

export const eventHours = [
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,]

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,
        },
    ],
},
{
    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: 16,
            endTime: 18,
        },
    ],
},]

所以我的想法是映射几天,每天我渲染 Flex 组件(我正在使用 ChakraUI),然后在该组件内,我映射当天的所有事件。对于每个事件,我都会按小时进行映射。如果小时小于事件 startTime,我将返回 true,如果它相等则返回 true,我正在创建一个布尔数组。

最后,我将通过该数组映射到真正返回空框组件上的空白区域,并在错误返回实际单元格组件上进行映射。

这是使其易于理解的代码

事件组件:我从数据中将其中两个渲染了 2 天

const Events = (props: Props) => {
return (
    <>
         <Box w='1000px' h='510px'>
        {scheduleData.map((day) => <EventFlex events={day.events} />)}
     </Box> 
    </>
)}

eventFlex 组件在这里发生的所有逻辑

我没有得到任何渲染,父 div 是空的。

interface Props {
    events: Event[]
}
type Event = {
    icon: string
    type: string
    title: string
    startTime: number
    endTime: number
}

const EventFlex = ({ events }: Props) => {

    const [emptyEventCells, setEmptyEventCells] = useState<boolean[]>([])
    const [myEvents, setEvents] = useState<Event[]>([])

    useEffect(() => {
        setEvents(events)
        generateEmptyEventCells()

    }, [])
    const generateEmptyEventCells = () => {
        let tempFlexItems: boolean[] = []

        myEvents.map(event => {
            eventHours.map(hour => {

                if (hour < event.startTime) {
                    tempFlexItems.push(true)
                }
                if (hour === event.startTime) {
                    tempFlexItems.push(false)
                }
            })
        })
        setEmptyEventCells(tempFlexItems)
    }
    const calculateEventLength = (startTime: number, endTime: number) => {
        return endTime - startTime;
    };

    return (<Flex h='102px'>
        {emptyEventCells.map((isEmpty: boolean, index) => (
            <React.Fragment>
                {isEmpty ? <Box w="83px"></Box> : <EventCell
                    size={`${calculateEventLength(myEvents[index].startTime, myEvents[index].endTime) * 83}`}
                    icon={myEvents[index].icon}
                    type={myEvents[index].type}
                    title={myEvents[index].title}
                    time={`${myEvents[index].startTime}h-${myEvents[index].endTime}h`}
                />}
            </React.Fragment>
        ))}
    </Flex>);

};
<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>

标签: reactjsflexboxternary

解决方案


三元运算符按预期工作,但我发现您的代码有 2 个错误和 1 个问题。

  1. 的错误用法useEffect。由于setEvents是异步的,调用generateEmptyEventCellsaftersetEvents(events)不会给出预期的结果。将其分解为 2 个 useEffects

  2. 的长度与emptyEventCells不同myEvents,因此,在 EventFlex 组件中,您不应使用emptyEventCellsas中的索引myEvents[index]。如果您想知道eventisEmpty价值相关的内容,最好找到另一种方法。

  3. 问题:如果从数组中渲染元素,比如使用 Array.map,您应该为key元素提供 prop。

最终代码是

EventFlex 组件

interface Props {
  events: Event[];
}

type Event = {
  icon: string;
  type: string;
  title: string;
  startTime: number;
  endTime: number;
};

type CellInfo = {
  isEmpty: boolean;
  event: Event;
};

const EventFlex = ({ events }: Props) => {
  const [emptyEventCells, setEmptyEventCells] = useState<CellInfo[]>([]);
  const [myEvents, setEvents] = useState<Event[]>([]);

  useEffect(() => {
    setEvents(events);
  }, []);
  useEffect(() => {
    generateEmptyEventCells();
  }, [myEvents]);
  const generateEmptyEventCells = () => {
    let tempFlexItems: CellInfo[] = [];

    myEvents.forEach((event) => {
      // use forEach if not returning anything
      eventHours.forEach((hour) => {
        // use forEach if not returning anything
        if (hour < event.startTime) {
          tempFlexItems.push({ isEmpty: true, event });
        }
        if (hour === event.startTime) {
          tempFlexItems.push({ isEmpty: false, event });
        }
      });
    });
    setEmptyEventCells(tempFlexItems);
  };
  const calculateEventLength = (startTime: number, endTime: number) => {
    return endTime - startTime;
  };
  return (
    <Flex h="102px">
      {emptyEventCells.map(({ isEmpty, event }, index) => (
        <React.Fragment key={`${index}`}>
          {isEmpty ? (
            <Box w="83px"></Box>
          ) : (
            <EventCell
              size={`${
                calculateEventLength(event.startTime, event.endTime) * 83
              }`}
              icon={event.icon}
              type={event.type}
              title={event.title}
              time={`${event.startTime}h-${event.endTime}h`}
            />
          )}
        </React.Fragment>
      ))}
    </Flex>
  );
};

事件组件

const Events = (props: Props) => {
  return (
    <>
      <Box w="1000px" h="510px">
        {scheduleData.map((day, index) => (
          <EventFlex events={day.events} key={`${index}`} /> // use key
        ))}
      </Box>
    </>
  );
};

这是代码沙盒演示:https ://codesandbox.io/s/young-firefly-cxvbh?file=/src/App.tsx


推荐阅读