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

时间:2018-07-18 08:52:03

标签: javascript arrays reactjs object

所以我正计划将事件压延,当前我正在获取具有开始价值的事件。我的事件以升序日期格式(后端格式)显示。

我的提取功能

// 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);

所以我的计划在看这段代码是通过事件数组进行映射,然后创建将显示月份的Subheader,然后通过检查对象开始日期将单个事件附加到该月的容器中。

我的问题是,最干净和可接受的方法是什么?我可以通过将事件的开始日期设置为子字符串来检查开始日期,该日期将为01、02、13(因为我想是其iso格式),然后在映射时检查if语句。但问题是,我需要创建最多12个子标题,并在其下根据开始日期附加事件。在我的情况下会是什么电流。谢谢

1 个答案:

答案 0 :(得分:0)

您可以简单地测试排序后的前一个磁贴中的月份是否与最后一个月相同。 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);

});