Javascript MobX商店没有';在react中无法获得更新 我想要达到的目标
我有一个store对象,我想用另一个对象的实例填充它的一个属性(它是一个空数组)。我希望我的一个react组件在所提到的数组实例的一部分发生更改时自动更新 我的问题是什么 通过注销此构造的store对象的值,我可以在浏览器控制台中看到更改,但当其值更改时,它不会在react组件中自动更新 所以我想得到一些提示,一些例子,来说明如何实现这样一个解决方案Javascript MobX商店没有';在react中无法获得更新 我想要达到的目标,javascript,reactjs,mobx,mobx-react,Javascript,Reactjs,Mobx,Mobx React,我有一个store对象,我想用另一个对象的实例填充它的一个属性(它是一个空数组)。我希望我的一个react组件在所提到的数组实例的一部分发生更改时自动更新 我的问题是什么 通过注销此构造的store对象的值,我可以在浏览器控制台中看到更改,但当其值更改时,它不会在react组件中自动更新 所以我想得到一些提示,一些例子,来说明如何实现这样一个解决方案 细节 我的项目 我想创建一个名为Session的MobX商店,它可以存储我的react webapp需要的所有东西。 此webapp将是一个文档
细节 我的项目 我想创建一个名为Session的MobX商店,它可以存储我的react webapp需要的所有东西。 此webapp将是一个文档处理工具,因此在创建新文档或加载现有文档后,我希望将文档对象添加到会话(添加到名为文档的对象数组中)。 更多详细信息:文档由一个或多个部分组成。因此,使用所见即所得编辑器,每次内容更改时,我都会将其内容添加到给定的部分 问题 我可以将新的文档添加到会话,我也可以更新节(我可以在控制台中注销节的值),但是使用对该文档和react组件中的节的会话引用,当节值更改时,它不会更新其状态。 根据我的理解,在我的示例中,文档的引用在节的值更改时不会更改,因此不会触发MobX作出反应 到目前为止我发现了什么 我开始在黑暗的网络深处挖掘,找到了这篇文章。 所以我开始感到兴奋,因为asStructure(或asMap)似乎解决了这个问题,但看起来MobX中的asStructure不受欢迎。 然后我找到了这个线索,其中提到了一个叫做observable.StructuralCompare的东西。但我在MobX文档中再次发现了这一点,所以我不知道如何实现它 所以我又卡住了,不知道如何解决这个问题 我的项目的代码摘录 以下是我在主react组件中引用所述会话值的方式:
import userSession from '../client/Session';
import {observer} from 'mobx-react';
@observer class App extends React.Component {
...
render() {
return (
...
<div>{JSON.stringify(userSession.documents[0].content.sections)}</div>
...
import userSession from '../../client/Session';
...
handleChange(value,arg2,arg3,arg4) {
this.setState({ content: value, delta: arg4.getHTML()});
userSession.documents[0].updateSectionContent(this.props.id, this.state.delta);
}
}
...
Session.js摘录:
class Session {
constructor(){
extendObservable(this, {
user: {
},
layout: {
},
documents: []
})
//current hack to add an empty Document to Session
this.documents.push(new Document());
}
//yadayadayada...
@action addNewSection() {
userSession.documents[0].content.sections.push({
type: "editor",
id: userSession.documents[0].getNextSectionID(),
editable: true,
content: "",
placeholder: "type here to add new section..."
});
}
}
var userSession = window.userSession = new Session();
export default userSession;
Document.js
import {extendObservable, computed, action} from "mobx";
import userSession from "./Session";
class Document {
constructor(doc = null) {
if (doc == null) {
console.log("doc - no init value provided");
extendObservable(this,{
labels: {
title: "title",
description: "description",
owners: ["guest"]
},
content: {
sections: [
{
type: "editor",
id: "sec1",
editable: true,
placeholder: "this is where the magic happens"
},
]
}
})
} else {
console.log("doc - init values provided: ");
extendObservable(this,{
labels: doc.labels,
content: doc.content
});
}
}
getNextSectionID(){
return `sec${this.content.sections.length}`;
}
@action updateSectionContent(sectionID, delta) {
console.log("doc - looking for section " + sectionID + " to update with this: " + delta);
let index = this.content.sections.findIndex(
section => section.id === sectionID
);
userSession.documents[0].content.sections[index].content = delta;
}
}
export default Document;
注:我不记得为什么我使文档属性可观察,但出于某种原因,这是必要的。不幸的是,您以错误的方式实现了
mobx
。为了让它更容易理解,我建议您研究一下mobx react
提供的HOCobserver
的实现
基本上,这个HOC所做的是将您的组件封装在另一个React组件中,该组件实现了shouldComponentUpdate
,当render
函数中引用的道具发生更改时,该组件将进行检查,并触发重新渲染。要使React组件对mobx
store中的更改作出反应,您需要将store数据作为props
传递给他们,可以采用React传统方式,也可以通过mobx React
提供的inject
HOC
虽然代码对存储中的更改没有反应,但问题是您导入存储并直接在组件内部使用它们,mobx react
无法检测到这种更改
要使其具有反应性,而不是导入它并直接在应用程序中使用它,您可以按如下方式将存储作为道具传递:
@observer
class App extends React.Component {
...
render() {
return (
...
<div>{this.props.sections}</div>
...);
}
}
您还可以在此处查看如何使用inject
只是一个建议:在直接跳到一些<代码>最佳模式之前,试着坚持基本的、标准的方式,即图书馆作者推荐和理解它是如何工作的,在你得到核心思想后你可以考虑其他选项。
你使用的模式不是装饰者的“标准”MOBX风格,因此,您将很难在方法上获得帮助(以及阅读自己的代码)。如果你换成那种风格,删掉所有与你的问题没有直接关系的描述,那就太好了。预期的行为是什么?您实际看到的行为是什么?我强调了带有标题的部分,并在开头添加了一个简单的摘要。我还认为所有必要的细节对理解我的问题都是有用的。我记得我选择这个解决方案是因为这样可以更容易地将所有这些东西都包含在构造函数中。这也是“标准”解决方案:不,它不是标准的,extendObservable的存在只是为了可以动态地将可观察属性添加到对象。因为您不需要动态添加可观察属性,所以不应该使用它。您也不应该使用构造函数。请参阅,感谢您努力教育我如何正确应用标准mobx功能。首先,我将在以后动态添加属性,也许这就是为什么我想在构造函数中尝试这一点(找不到相应的SO线程,但我从这里复制了一个解决方案)。若不设置对象的初始值,那个么构造函数是用来做什么的呢?第二,可能是我不了解mobx的概念,但在陷阱页面上没有发现任何相关内容。你指的是什么?第三,如果您能就我的实际问题提出一些建议,我将不胜感激。Thx!:)好吧,我病了,但我回来了。我已经做了你推荐的,但是仍然没有更新。问题出在存储和另一个对象的某个地方,该对象被分配给一个存储属性(数组)。我将对象添加到存储中,但当对象属性更新时,它不会触发存储中的更新。
<App sections={userSession.documents[0].content.sections} />