【问题标题】:How to use react context with nested mobx stores?如何在嵌套的 mobx 商店中使用反应上下文?
【发布时间】:2019-11-15 15:16:40
【问题描述】:

我有两家商店:formStoreprofileStore

FormStore

export class ProfileFormStore {
    @observable editing = false;
    profileStore = new ProfileStore(this.roleId);
    originalValue?: ApiModel | null;

    @action.bound
    startEdit() {
        // this.originalValue = this.profileStore.toJson();  
/*  if uncomment above, next error thrown
    RangeError: Maximum call stack size exceeded
    at initializeInstance (mobx.module.js:391)
    at ProfileStore.get (mobx.module.js:381)
    at ProfileStore.get
*/
        this.editing = true;
    }
}

ProfileStore

export class ProfileStore {
    @observable userProfile: ApiModel = {
        userProfile: {
            newsAndUpdates: false,
            email: "",
            phone: "",
            lastName: "",
            firstName: "",
        },
    };

    @observable email = "";

    @action.bound
    fetch() {
        // this.fromJson(this.actions.fetch());
        console.log("start");
        this.email = "qwe";
        console.log("end");
    }

    @computed
    toJson(): ApiModel {
        return {
            userProfile: {
                firstName: this.userProfile.userProfile.firstName,
                lastName: this.userProfile.userProfile.lastName,
                phone: this.userProfile.userProfile.phone,
                email: this.userProfile.userProfile.email,
                newsAndUpdates: this.userProfile.userProfile.newsAndUpdates,
            },
        };
    }
}

我想使用上下文

const formStore = new ProfileFormStore();
export const profileFormContext = React.createContext({
    formStore,
    profileStore: formStore.profileStore,
});

export const useProfileContext = () => React.useContext(profileFormContext);

还有两个组件:formformControl

const controls = {
    admin: (<><ProfileName /><Email /></>),
    user: (<><ProfileName /></>)
};
export const Form = () => {
    const { formStore, profileStore } = useProfileContext();
    // this.fromJson(this.actions.fetch()); // if uncomment throws 'Missing option for computed get'

    return <form>(controls.admin)</form>
}

export const ProfileName = () => {
    const { formStore, profileStore } = useProfileContext();
    formStore.startEdit(); // check form store, when assigning from profileStore get overflow error

    return formStore.editing ? <input value='test' /> : <label>Test</label>
}

所以有两种错误:

  1. ProfileStore 访问observables 时,这是FormStore 的一部分
  2. ProfileStore 中更新observables 时,这是FormStore 的一部分

FormStore 运行良好

通过React.useContext 注入的两个商店都遵循这些示例https://mobx-react.js.org/recipes-context,但是它们的商店没有嵌套。我让它们嵌套,因为我想从formStore 访问profileStore

这些错误是什么意思?如何解决?

【问题讨论】:

  • 我不确定在 React 的上下文中使用 MobX 是否是个好主意,也许可以尝试不同的方法,除非你有这样做的理由
  • 对不起,我不知道“儿童不吸毒”,好吧我没有更新,我想我暂时无法提出任何建议
  • 除非您的名为“userProfile”的“userProfile”属性也是可观察的,否则不会自动触发计算的“toJson”。目前所有“名字,姓氏等”的任何更改。不会触发任何动作。
  • @AntoanElenkov 来自mobx.js.org/refguide/observable.htmlIf value is an object without prototype, all its current properties will be made observable.。我想,它应该递归应用。顺便说一句,当手动触发toJson 时,我得到Maximum call stack size exceeded 错误

标签: reactjs react-hooks mobx react-context


【解决方案1】:

其实这不是答案 :) 但我用过的解决方案

export class ProfileStore {
   @observable editing;
   @observablt userProfile: UserProfile;
   ...
}

就是这样 - 现在有一家商店,而不是使用两家商店,我很高兴该解决方案有效。我认为错误是我忘记在toJsonget。如果将来我遇到同样的错误并理解它发生的原因。我会尽量不要忘记更新这个答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-11
    • 1970-01-01
    • 2021-11-21
    • 2021-02-09
    • 1970-01-01
    • 1970-01-01
    • 2019-08-21
    相关资源
    最近更新 更多