我想重新创建类似WhatsApp / Telegram的时间轴,其中消息按天划分。
为了在React中渲染消息,我使用Object.key(messages).map函数。
Object.keys(this.messages).map(e => {
return <div key={i++}>
{ this.messages[e] }
如何添加例如在昨天的最后一天和今天的第一个消息之间是“今天”?
答案 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)
上,并为每个键返回div
或span
和一个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天)的范围内,则会显示“今日”标签。
在初始状态下,将labelAlreadyPresent
和showLabel
设置为假