Javascript React映射对象数组按值创建容器并将对象插入该容器

Javascript React映射对象数组按值创建容器并将对象插入该容器,javascript,arrays,reactjs,object,Javascript,Arrays,Reactjs,Object,所以我计划制作活动日历,目前我正在获取具有开始值的活动。我的事件以升序日期格式(在后端格式化) 我的取数函数 // Get events export const getEvents = () => dispatch => { dispatch(setEventLoading()); axios .get('http://localhost:3001/events/') .then(res => dispatch({ typ

所以我计划制作活动日历,目前我正在获取具有开始值的活动。我的事件以升序日期格式(在后端格式化)

我的取数函数

// Get events
export const getEvents = () => dispatch => {
  dispatch(setEventLoading());
  axios
    .get('http://localhost:3001/events/')
    .then(res => 
      dispatch({
        type: GET_EVENTS,
        payload: res.data
      })
    );
};
事件模型:

const eventSchema = new Schema({
  creator: {
    type: Schema.Types.ObjectId,
    ref: 'User'
  },
  title: {
    type: String,
    required: true
  },
  description: {
    type: String,
    required: true
  },
  location: {
    type: String
  },
  photo: {
    type: String
  },
  start: {
    type: Date
  },
  end: {
    type: Date
  },
  going: [
    {
      user: {
        type: Schema.Types.ObjectId,
        ref: 'User'
      }
    }
  ],
  comments: [
    {
      user: {
        type: Schema.Types.ObjectId,
        ref: 'User'
      },
      text: {
        type: String,
        required: true
      },
      name: {
        type: String
      },
      date: {
        type: Date,
        default: Date.now
      }
    }
  ],
  date: {
    type: Date,
    default: Date.now
  }
});
所以我的计划是按月份顺序显示事件。 映射并显示事件的UI组件:

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import GridList from '@material-ui/core/GridList';
import GridListTile from '@material-ui/core/GridListTile';
import GridListTileBar from '@material-ui/core/GridListTileBar';
import ListSubheader from '@material-ui/core/ListSubheader';
import IconButton from '@material-ui/core/IconButton';
import InfoIcon from '@material-ui/icons/Info';
import ButtonBase from '@material-ui/core/ButtonBase';
import Typography from '@material-ui/core/Typography';
const dateFormat = require('dateformat');
const styles = theme => ({
  root: {
    display: 'flex',
    flexWrap: 'wrap',
    justifyContent: 'space-around',
    overflow: 'hidden',
    backgroundColor: theme.palette.background.paper,
  },
  gridList: {
    width: 650,
    height: 550,
  },
  icon: {
    color: 'rgba(255, 255, 255, 0.54)',
  },
  image: {
    position: 'relative',
    height: 200,
    [theme.breakpoints.down('xs')]: {
      width: '100% !important', // Overrides inline-style
      height: 100,
    },
    '&:hover, &$focusVisible': {
      zIndex: 1,
      '& $imageBackdrop': {
        opacity: 0.15,
      },
      '& $imageMarked': {
        opacity: 0,
      },
      '& $imageTitle': {
        border: '4px solid currentColor',
      },
    },
  },
});


function TitlebarGridList(props) {
  const { classes } = props;

  return (
    <div className={classes.root}>
      <GridList cellHeight={180} className={classes.gridList}>
        <GridListTile key="Subheader" cols={2} style={{ height: 'auto' }}>
          <ListSubheader component="div">December</ListSubheader>
        </GridListTile>
        {props.events.map(tile => (

          <GridListTile key={tile._id}>

            <ButtonBase
          focusRipple
          key={tile._id}
          className={classes.image}
          focusVisibleClassName={classes.focusVisible}
          style={{
            width: '100%',
          }}
        >
          <span
            className={classes.imageSrc}
            style={{
              backgroundImage: `url(${tile.photo})`,
            }}
          />
          <span className={classes.imageBackdrop} />
          <span className={classes.imageButton}>
            <Typography
              component="span"
              variant="subheading"
              color="inherit"
              className={classes.imageTitle}
            >
              {dateFormat(tile.start, "dddd dS,  h:MM TT")}
              <span className={classes.imageMarked} />
            </Typography>
          </span>
        </ButtonBase>
            <GridListTileBar
              title={tile.title}
              subtitle={<span>by: {tile._id}</span>}
              actionIcon={
                <IconButton className={classes.icon}>
                  <InfoIcon />
                </IconButton>
              }
            />
          </GridListTile>
        ))}
      </GridList>
    </div>
  );
}

TitlebarGridList.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(TitlebarGridList);
从“React”导入React;
从“道具类型”导入道具类型;
从“@material ui/core/styles”导入{withStyles}”;
从“@material ui/core/GridList”导入网格列表;
从“@material ui/core/GridListTile”导入GridListTile;
从“@material ui/core/GridListTileBar”导入GridListTileBar;
从“@material ui/core/ListSubheader”导入列表子标题;
从“@material ui/core/IconButton”导入IconButton;
从“@material ui/icons/Info”导入信息图标;
从“@material ui/core/ButtonBase”导入按钮库;
从“@material ui/core/Typography”导入排版;
const dateFormat=require('dateFormat');
常量样式=主题=>({
根目录:{
显示:“flex”,
flexWrap:“wrap”,
为内容辩护:“周围的空间”,
溢出:“隐藏”,
背景色:theme.palete.background.paper,
},
网格列表:{
宽度:650,
身高:550,
},
图标:{
颜色:“rgba(255,255,255,0.54)”,
},
图片:{
位置:'相对',
身高:200,
[主题.breakpoints.down('xs')]:{
宽度:“100%”重要“,//替代内联样式
身高:100,
},
“&:hover,&$focusVisible”:{
zIndex:1,
“&$imagebackground”:{
不透明度:0.15,
},
“&$imageMarked”:{
不透明度:0,
},
“&$imageTitle”:{
边框:“4px实心currentColor”,
},
},
},
});
函数标题栏列表(道具){
常量{classes}=props;
返回(
十二月
{props.events.map(tile=>(
{dateFormat(tile.start,“dddd-dS,h:MM-TT”)}
))}
);
}
TitlebarGridList.propTypes={
类:PropTypes.object.isRequired,
};
导出默认样式(样式)(标题栏列表);
所以我的计划是在这段代码中映射事件数组,然后创建子标题来显示月份,然后通过检查对象的开始日期将单个事件附加到该月份的容器中


我的问题是什么是最干净和可接受的方法。我可以通过将事件开始日期子串到一个月来进行检查,这个月将是01、02、13(我猜是iso格式),然后在映射时使用if语句进行检查。但问题是,我需要创建最多12个子标题,并根据开始日期在其下附加事件。在我的情况下,电流是多少。谢谢

排序后,您可以简单地测试上一个磁贴中的月份是否与上一个相同。Lodash非常适合分类:

import _ from 'lodash'

const monthNames = ["January", "February", "March", "April", "May", "June",
  "July", "August", "September", "October", "November", "December"];
let lastMonth = monthNames[0];

function getMonthName(date) {
    return monthNames[date.getMonth()]);
}



{_.sortBy(props.events, ['date']).map(tile => {

    if(getMonthName(tile.date) !== lastMonth) {
        <GridListTile key="Subheader" cols={2} style={{ height: 'auto' }}>
          <ListSubheader component="div">December</ListSubheader>
        </GridListTile>
    }

    return (<GridListTile key={tile._id}>

            <ButtonBase
          focusRipple
          key={tile._id}
          className={classes.image}
          focusVisibleClassName={classes.focusVisible}
          style={{
            width: '100%',
          }}
        >
          <span
            className={classes.imageSrc}
            style={{
              backgroundImage: `url(${tile.photo})`,
            }}
          />
          <span className={classes.imageBackdrop} />
          <span className={classes.imageButton}>
            <Typography
              component="span"
              variant="subheading"
              color="inherit"
              className={classes.imageTitle}
            >
              {dateFormat(tile.start, "dddd dS,  h:MM TT")}
              <span className={classes.imageMarked} />
            </Typography>
          </span>
        </ButtonBase>
            <GridListTileBar
              title={tile.title}
              subtitle={<span>by: {tile._id}</span>}
              actionIcon={
                <IconButton className={classes.icon}>
                  <InfoIcon />
                </IconButton>
              }
            />
          </GridListTile>);

    lastMonth = getMonthName(tile.date);

});
从“lodash”导入 const monthNames=[“一月”、“二月”、“三月”、“四月”、“五月”、“六月”, “七月”、“八月”、“九月”、“十月”、“十一月”、“十二月”]; 设lastMonth=monthNames[0]; 函数getMonthName(日期){ 返回月份名称[date.getMonth()]; } {{.sortBy(props.events,['date']).map(tile=>{ 如果(getMonthName(平铺日期)!==上月){ 十二月 } 返回( {dateFormat(tile.start,“dddd-dS,h:MM-TT”)} ); lastMonth=getMonthName(tile.date); });