我希望能够重新创建类似于WhatsApp / Telegram的时间线,其中消息按天分开。
在React中呈现消息时,我使用Object.key(messages).map函数。
Object.keys(this.messages).map(e => {
return <div key={i++}>
{ this.messages[e] }
如何在昨天的最后一条消息和今天的第一条消息之间添加“今天”等内容?
我希望能够重新创建类似于WhatsApp / Telegram的时间线,其中消息按天分开。
在React中呈现消息时,我使用Object.key(messages).map函数。
Object.keys(this.messages).map(e => {
return <div key={i++}>
{ this.messages[e] }
// 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)
,并为每个键返回一个带有className="date-label"
(示例)的div
或span
。 如果从此键提取的日期等于(new Date()).getDate()
- 渲染“今天”,如果是(new Date()).getDate() - 1
- 渲染“昨天”,否则渲染“X天前”。 现在,在此map
循环中,您还需要map
over groupedByDate[key]
(来自当天的消息数组)并呈现消息。
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天)的范围内,则显示“今天”标签。
在初始状态下,将labelAlreadyPresent
和showLabel
设置为false。