如果你有一个 observable
在您的商店中列出:
@obserable public Claimslist: IClaim[] = [];
哪里IClaim
是一个接口(interface),claims
是 IClaim
的数组对象
IClaim
在其对象中包含一个名为 moveOutDate
的变量
每个 claim 对象都有 id
变量。
现在您想通过 claim
更新或获取该变量编号
所以你有两个函数:
获取
/**
* Gets the moveOutDate of a claim by claim ID
*/
@action getMoveOutDateById = (id: string) => {
// Get the claim by id
const claim = this.Claimslist.find((element: IClaim) => element.id === sessionStorage.getItem('claim-id'));
if (claim) {
if (!claim.moveOutDate) {
return undefined;
}
return moment(new Date(claim.moveOutDate)).toDate();
}
return undefined;
}
设置
/**
* Sets moveOutDate in claim by claim ID
*/
@action public setMoveOutDate = (id: string, date: Date) => {
const claim = this.Claimslist.find((element: IClaim) => element.id === id);
if (claim) {
claim.moveOutDate = date.toString();
}
}
好的,但是现在当你使用 getMoveOutDateById
时一开始在你的render
它可以工作并呈现日期,但是一旦您调用 setMoveOutDate
onUpdate
日期组件的渲染不会更新,但商店会更新,只有刷新页面才能看到更改。
现在我设法解决了这个问题,方法是:
this.Claimslist = this.Claimslist.slice();
并添加 Claimslist 的隐藏输入:
const {Claimslist} = this.props.claimsStore;
和
<input type="hidden" value={Claimslist} />
如果整个对象是obserable
,为什么会这样?并用 @action
包裹为什么不使用 slice()
不改变并有一个隐藏的输入?
最佳答案
Mobx observable
只观察浅值。意思是说我有 @observable claims[]
然后 claims[0] = something
会触发更新但是 claims[0].foo = bar
不会 (docs) .要解决此问题,您需要通过在 claim
对象上添加 @observable foo
来使 foo
也可观察。
考虑以下示例。请注意 Claim1
和 Claim2
之间的区别。组件完全相同,但 ClaimView2
会更新,而 ClaimView1
不会。 Demo
import React from "react";
import { render } from "react-dom";
import { observable, action } from "mobx";
import { observer } from "mobx-react";
class Claim1 {
moveOutDate: Date;
constructor() {
this.moveOutDate = new Date();
}
}
@observer
class ClaimsView1 extends React.Component {
@observable claims: Claim1[] = [
new Claim1(),
new Claim1()
];
@action.bound
updateClaims(){
this.claims.forEach(claim => {
claim.moveOutDate = new Date();
})
}
render() {
return <div>
<pre>
{"ClaimsView1 = \n" + JSON.stringify(this.claims, null, " ")}
</pre>
<button onClick={this.updateClaims}> Update </button>
</div>
}
}
class Claim2 {
@observable moveOutDate: Date;
constructor() {
this.moveOutDate = new Date();
}
}
@observer
class ClaimsView2 extends React.Component {
@observable claims: Claim2[] = [
new Claim2(),
new Claim2()
];
@action.bound
updateClaims(){
this.claims.forEach(claim => {
claim.moveOutDate = new Date();
})
}
render() {
return <div>
<pre>
{"ClaimsView2 = \n" + JSON.stringify(this.claims, null, " ")}
</pre>
<button onClick={this.updateClaims}> Update </button>
</div>
}
}
render(
<>
<ClaimsView1 />
<ClaimsView2 />
</>,
document.getElementById("root")
);
更新:
这是一个 demo对于我在评论中给出的解决方案
import React from "react";
import { render } from "react-dom";
import { observable, action } from "mobx";
import { observer } from "mobx-react";
interface IClaim {
moveOutDate: Date;
}
@observer
class ClaimsView extends React.Component<{claims: IClaim[]}> {
@observable claims: IClaim[] = this.props.claims.map(claim => observable(claim))
updateClaims = () => {
this.claims.forEach(claim => {
claim.moveOutDate = new Date();
})
}
render() {
return <div>
<pre>
{"claims = \n" + JSON.stringify(this.claims, null, " ")}
</pre>
<button onClick={this.updateClaims}> Update </button>
</div>
}
}
render(
<ClaimsView claims={[
{ moveOutDate: new Date() },
{ moveOutDate: new Date() }
]} />,
document.getElementById("root")
);
关于javascript - ReactJS mobx - 不更新可观察数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55262053/