Вы должны создать правильный фрейм, вот метод:
static private byte[] CreateFrame(string message, MessageType messageType = MessageType.Text, bool messageContinues = false)
{
byte b1 = 0;
byte b2 = 0;
switch (messageType)
{
case MessageType.Continuos:
b1 = 0;
break;
case MessageType.Text:
b1 = 1;
break;
case MessageType.Binary:
b1 = 2;
break;
case MessageType.Close:
b1 = 8;
break;
case MessageType.Ping:
b1 = 9;
break;
case MessageType.Pong:
b1 = 10;
break;
}
b1 = (byte)(b1 + 128); // set FIN bit to 1
byte[] messageBytes = Encoding.UTF8.GetBytes(message);
if (messageBytes.Length < 126)
{
b2 = (byte)messageBytes.Length;
}
else
{
if (messageBytes.Length < Math.Pow(2,16)-1)
{
b2 = 126;
}
else
{
b2 = 127;
}
}
byte[] frame = null;
if(b2 < 126)
{
frame = new byte[messageBytes.Length + 2];
frame[0] = b1;
frame[1] = b2;
Array.Copy(messageBytes, 0, frame, 2, messageBytes.Length);
}
if(b2 == 126)
{
frame = new byte[messageBytes.Length + 4];
frame[0] = b1;
frame[1] = b2;
byte[] lenght = BitConverter.GetBytes(messageBytes.Length);
frame[2] = lenght[1];
frame[3] = lenght[0];
Array.Copy(messageBytes, 0, frame, 4, messageBytes.Length);
}
if(b2 == 127)
{
frame = new byte[messageBytes.Length + 10];
frame[0] = b1;
frame[1] = b2;
byte[] lenght = BitConverter.GetBytes((long)messageBytes.Length);
for(int i = 7, j = 2; i >= 0; i--, j++)
{
frame[j] = lenght[i];
}
}
return frame;
}
Вы показываете все даты как оригинальные, и при нажатии вы хотите, чтобы все даты на странице были обновлены до форматированной версии даты.
В вашем коде вы фактически изменяете дату в состоянии - но вы не должны этого делать, вместо этого вы должны хранить логическое значение (datesFormatted
), которое сообщит вам, следует ли отображать отформатированную дату или нет.
Ваша функция переключения будет выглядеть следующим образом:
toggleDate() {
// reverse the current state
this.setState({
datesFormatted: !this.state.datesFormatted,
})
}
и ваш код рендеринга даты будет выглядеть так:
{job.StartedOn ? (<span onClick={this.toggleDate}>{this.state.datesFormatted ? moment(job.StartedOn).fromNow() : job.StartedOn}</span>) : 'No date'}
Если вы хотите, чтобы даты изменялись индивидуально, и не все сразу - тогда вы бы хотели, чтобы каждая дата содержала свое собственное состояние. В этом случае вам нужно создать дочерний компонент, который имеет свое собственное состояние.
class DateToggle extends Component {
constructor() {
super();
this.state = {
showFormatted: true,
}
}
handleToggle = () => {
this.setState({
showFormatted: !this.state.showFormatted,
})
}
render() {
let displayDate = this.props.date;
if (this.state.showFormatted) {
displayDate = moment(displayDate).fromNow()
}
return <span onClick={this.handleToggle}>{displayDate}</span>
}
}
, а затем в родительском компоненте вы можете просто указать в нем дату своей работы:
render() {
return jobs.map((job, index) => (<DateToggle date={job.StartedOn} />));
}
Как только вы сделаете это:
this.setState({
date_to_show: date
});
Компоненты Rect, зависящие от этой переменной состояния, изменятся. Вот как работает государство в реакции. (Поправьте меня, если я ошибаюсь).
Вы можете сохранить массив как переменную состояния, чтобы решить эту проблему.
Измените эту строку и попробуйте:
{ job.StartedOn ?
<div onClick={() => this.toggleBetweenDates(job.StartedOn,index)}>
{this.state.date_to_show[index] ? this.state.date_to_show[index] :
moment(job.StartedOn).fromNow()}</div>
:
'No date'
}
А внутри функции даты переключения:
toggleBetweenDates(date: Date,index:number): void {
this.setState({
date_to_show[index]: date
});