在 React 组件中格式化 moment 对象
Formatting a moment object within a React component
我有一组 date/time 个字符串,我试图将它们作为 moment
个对象存储在我的 React 应用程序的状态树中。然后我试图在我的组件中显示这些格式化的对象,如下所示:
{ ticket.reportDateUtc.format('YYYY-MM-DD hh:mm a') }
当我尝试在我的 React 应用程序中查看此组件时,这会导致以下错误:
TypeError: ({_isAMomentObject:true, _i:"2015-10-05T20:06:58Z",
_f:"YYYY-MM-DDTHH:mm:ssZ", _tzm:-0, _isUTC:false,
_pf:{empty:false, unusedTokens:[], unusedInput:[], overflow:-1, charsLeftOver:0, nullInput:false, invalidMonth:null, invalidFormat:false, userInvalidated:false, iso:true},
_locale:{_ordinalParse:/\d{1,2}(th|st|nd|rd)/, ordinal:(function (number) {
"use strict";
var b = number % 10,
output = (toInt(number % 100 / 10) === 1) ? 'th' :
(b === 1) ? 'st' :
(b === 2) ? 'nd' :
(b === 3) ? 'rd' : 'th';
return number + output;
}), _abbr:"en", _ordinalParseLenient:/\d{1,2}(th|st|nd|rd)|\d{1,2}/}, _d:(new Date(1444075618000))}) is not extensible
但是,如果我在将 moment
保存到状态时将其格式化为字符串,然后在组件中显示该字符串,它会成功显示(但我不想这样做,以便我可以重复使用具有不同格式选项的对象)。 react docs 似乎表明我使用了正确的语法(他们的示例完全相同,但使用了 Javascript 的内置 Date
对象)。是我做错了什么,还是 moment 库在 React 组件中无法正常工作?
编辑:这是出现问题的渲染方法之一:
render() {
const ticket = this.props.ticket;
const notes = ticket.notes.map(note => <TicketRowNote key={note.id} note={note}/>);
return (
<tr className="pointer" onClick={history.replaceState.bind(this, null, `/tickets/${ticket.id}`)}>
<td>{ ticket.id }</td>
<td>
<i className="fa fa-flag"/>
</td>
<td className="text-right no-break">{ ticket.reportDateUtc.format('YYYY-MM-DD hh:mm a') }</td>
<td className="text-right no-break">{ ticket.lastUpdated.format('YYYY-MM-DD hh:mm a') }</td>
<td className="text-center">{ ticket.problemtype.detailDisplayName }</td>
<td>
<OverlayTrigger trigger={ ["hover", "focus"] } placement="bottom"
overlay={<Popover id={ "detail-" + ticket.id + "-popover" } title={ ticket.subject }><span dangerouslySetInnerHTML={ helpers.getMarkup(ticket.detail) }/></Popover>}>
<div className="detail-wrapper">
<strong>{ ticket.subject }</strong>
</div>
</OverlayTrigger>
</td>
<td>
{ notes }
</td>
<td className="no-break"><a href={ "mailto:" + ticket.clientReporter.email }><i
className="fa fa-envelope-o"/></a> { ticket.displayClient }
</td>
<td className="text-center">{ ticket.statustype.statusTypeName }</td>
<td className="text-center no-break">{ ticket.prioritytype.priorityTypeName }</td>
<td className="no-break"><a href={ "mailto:" + ticket.clientTech.email }><i
className="fa fa-envelope-o"/></a> { ticket.clientTech.displayName }
</td>
</tr>
);
}
以及更新状态的方法(我知道这看起来很糟糕,不幸的是我正在处理一个糟糕的问题API):
export function retrieveTickets(scope) {
tree.set('isLoading', true);
api.getTickets(scope).then((res) => {
let tickets = [];
// Extremely annoying workaround for WHD being terrible
let count = res.length;
res.forEach(function (ticket) {
api.getTicketDetail(ticket.id).then((res) => {
for (let attr in res) {
if (res.hasOwnProperty(attr)) {
ticket[attr] = res[attr];
}
}
ticket.lastUpdated = moment(ticket.lastUpdated).add(4, 'hours');
ticket.notes = slice(ticket.notes, 0, 2).map(function (note) {
note.commenterName = helpers.extractCommenterName(note.prettyUpdatedString);
note.strippedText = helpers.stripTags(note.mobileNoteText);
return note;
});
ticket.reportDateUtc = moment(ticket.reportDateUtc);
if (ticket.closeDate) {
ticket.closeDate = moment(ticket.closeDate).add(4, 'hours');
}
if (ticket.displayDueDate) {
ticket.displayDueDate = moment(ticket.displayDueDate).add(4, 'hours');
}
tickets.push(ticket);
if (tickets.length === count) {
tree.set('tickets', tickets);
tree.set('isLoading', false);
}
});
});
});
}
我认为您的问题是 baobab
冻结了提供给它的对象,并且 moment
对象在您调用 format
时会自行修改。
尝试配置 baobab 并将 immutable
设置为 false,看看是否能解决问题。
我有一组 date/time 个字符串,我试图将它们作为 moment
个对象存储在我的 React 应用程序的状态树中。然后我试图在我的组件中显示这些格式化的对象,如下所示:
{ ticket.reportDateUtc.format('YYYY-MM-DD hh:mm a') }
当我尝试在我的 React 应用程序中查看此组件时,这会导致以下错误:
TypeError: ({_isAMomentObject:true, _i:"2015-10-05T20:06:58Z",
_f:"YYYY-MM-DDTHH:mm:ssZ", _tzm:-0, _isUTC:false,
_pf:{empty:false, unusedTokens:[], unusedInput:[], overflow:-1, charsLeftOver:0, nullInput:false, invalidMonth:null, invalidFormat:false, userInvalidated:false, iso:true},
_locale:{_ordinalParse:/\d{1,2}(th|st|nd|rd)/, ordinal:(function (number) {
"use strict";
var b = number % 10,
output = (toInt(number % 100 / 10) === 1) ? 'th' :
(b === 1) ? 'st' :
(b === 2) ? 'nd' :
(b === 3) ? 'rd' : 'th';
return number + output;
}), _abbr:"en", _ordinalParseLenient:/\d{1,2}(th|st|nd|rd)|\d{1,2}/}, _d:(new Date(1444075618000))}) is not extensible
但是,如果我在将 moment
保存到状态时将其格式化为字符串,然后在组件中显示该字符串,它会成功显示(但我不想这样做,以便我可以重复使用具有不同格式选项的对象)。 react docs 似乎表明我使用了正确的语法(他们的示例完全相同,但使用了 Javascript 的内置 Date
对象)。是我做错了什么,还是 moment 库在 React 组件中无法正常工作?
编辑:这是出现问题的渲染方法之一:
render() {
const ticket = this.props.ticket;
const notes = ticket.notes.map(note => <TicketRowNote key={note.id} note={note}/>);
return (
<tr className="pointer" onClick={history.replaceState.bind(this, null, `/tickets/${ticket.id}`)}>
<td>{ ticket.id }</td>
<td>
<i className="fa fa-flag"/>
</td>
<td className="text-right no-break">{ ticket.reportDateUtc.format('YYYY-MM-DD hh:mm a') }</td>
<td className="text-right no-break">{ ticket.lastUpdated.format('YYYY-MM-DD hh:mm a') }</td>
<td className="text-center">{ ticket.problemtype.detailDisplayName }</td>
<td>
<OverlayTrigger trigger={ ["hover", "focus"] } placement="bottom"
overlay={<Popover id={ "detail-" + ticket.id + "-popover" } title={ ticket.subject }><span dangerouslySetInnerHTML={ helpers.getMarkup(ticket.detail) }/></Popover>}>
<div className="detail-wrapper">
<strong>{ ticket.subject }</strong>
</div>
</OverlayTrigger>
</td>
<td>
{ notes }
</td>
<td className="no-break"><a href={ "mailto:" + ticket.clientReporter.email }><i
className="fa fa-envelope-o"/></a> { ticket.displayClient }
</td>
<td className="text-center">{ ticket.statustype.statusTypeName }</td>
<td className="text-center no-break">{ ticket.prioritytype.priorityTypeName }</td>
<td className="no-break"><a href={ "mailto:" + ticket.clientTech.email }><i
className="fa fa-envelope-o"/></a> { ticket.clientTech.displayName }
</td>
</tr>
);
}
以及更新状态的方法(我知道这看起来很糟糕,不幸的是我正在处理一个糟糕的问题API):
export function retrieveTickets(scope) {
tree.set('isLoading', true);
api.getTickets(scope).then((res) => {
let tickets = [];
// Extremely annoying workaround for WHD being terrible
let count = res.length;
res.forEach(function (ticket) {
api.getTicketDetail(ticket.id).then((res) => {
for (let attr in res) {
if (res.hasOwnProperty(attr)) {
ticket[attr] = res[attr];
}
}
ticket.lastUpdated = moment(ticket.lastUpdated).add(4, 'hours');
ticket.notes = slice(ticket.notes, 0, 2).map(function (note) {
note.commenterName = helpers.extractCommenterName(note.prettyUpdatedString);
note.strippedText = helpers.stripTags(note.mobileNoteText);
return note;
});
ticket.reportDateUtc = moment(ticket.reportDateUtc);
if (ticket.closeDate) {
ticket.closeDate = moment(ticket.closeDate).add(4, 'hours');
}
if (ticket.displayDueDate) {
ticket.displayDueDate = moment(ticket.displayDueDate).add(4, 'hours');
}
tickets.push(ticket);
if (tickets.length === count) {
tree.set('tickets', tickets);
tree.set('isLoading', false);
}
});
});
});
}
我认为您的问题是 baobab
冻结了提供给它的对象,并且 moment
对象在您调用 format
时会自行修改。
尝试配置 baobab 并将 immutable
设置为 false,看看是否能解决问题。