在.map()函数中的第一个键之前附加元素

时间:2018-08-17 14:48:23

标签: javascript reactjs

我想重新创建类似WhatsApp / Telegram的时间轴,其中消息按天划分。
为了在React中渲染消息,我使用Object.key(messages).map函数。

Object.keys(this.messages).map(e => {
    return <div key={i++}>
              { this.messages[e] }

如何添加例如在昨天的最后一天和今天的第一个消息之间是“今天”?

2 个答案:

答案 0 :(得分:1)

我会将所有消息分成单独的数组,每一天发生一次。为此,请创建一个对象-其键将是唯一的日子,其值将是这几天的消息。

// object similar to your 'messages' state
const messages = {
  message1: {
    body: "one day before message",
    time: 1534433188201
  },
  message2: {
    body: "newest message",
    time: 1534519588201
  },
  message3: {
    body: "2 days before newest message",
    time: 1534346788201
  },
  message4: {
    body: "also 2 days before newest message",
    time: 1534346788250
  }
};
// creating array from your object
const messagesArray = Object.keys(messages).map(m => messages[m]);
// sorting array - oldest to newest
const latestMessages = messagesArray.sort((a, b) => a.time > b.time);
// grouping by date - create an object, each key is a different date and value is an array of messages from that day
const groupedByDate = {};
latestMessages.forEach(message => {
  const date = new Date(message.time);
  const day = date.getDate();
  const month = date.getMonth();
  const year = date.getFullYear();
  // this will create 'date_17-7-2018' format as an example - you can do whatever you want/need here
  const key = `date_${day}-${month}-${year}`;
  // push message to existing key or create new array containing this message
  if(groupedByDate[key]) {
    groupedByDate[key].push(message);
  } else {
    groupedByDate[key] = [message];
  }
});
console.log(groupedByDate);

现在渲染部分似乎很容易-这是我如何实现此效果的示例:

映射到Object.keys(groupedByDate)上,并为每个键返回divspan和一个className="date-label"(示例)。如果从此键中提取的日期等于(new Date()).getDate()-渲染“今天”,如果是(new Date()).getDate() - 1-渲染“昨天”,否则渲染“ X天前”。现在,在此map循环中,您还需要map(从今天开始的消息数组)上groupedByDate[key]并呈现消息。

答案 1 :(得分:0)

    Object.keys(this.messages).map(message => {
      const date = new Date();
      date.setHours(0,0,0,0);  // will set to midnight
      const today = Math.round(date.getTime() / 1000);
      const timeDifference = this.state.time - today;
      const isInRange = timeDifference >= 0 && timeDifference <=86400;
      if (isInRange && !this.state.labelAlreadyPresent) {
        this.setState({ showLabel: true, labelAlreadyPresent: true });
      } else if(!isInRange) {
         this.setState({ labelAlreadyPresent: false, showLabel: true });
      } else {
         this.setState({ showLabel: false });
      }

      return (
         <div key={message.time}>
           {this.state.showLabel && <label> Today </label>}
           { message.body }
         </div>
       );

因此,基本上,您首先要获取今天的日期并将其设置为午夜。那么您将获得以秒为单位的Unix时间戳。之后,将时间戳与收到的响应进行比较,如果时间戳在0到86400(等于1天)的范围内,则会显示“今日”标签。

在初始状态下,将labelAlreadyPresentshowLabel设置为假