Как подключить магазин Mobx6 к компоненту react 15.8? «Неперехваченное инвариантное нарушение, крючки могут вызываться только внутри тела компонента функции»

#javascript #typescript #mobx #mobx-react

Вопрос:

Я пытаюсь подключиться к магазину mobx к своему компоненту react.

версии библиотеки:

  "mobx": "^6.3.2"
 "mobx-react": "^7.2.0"
 "react": "16.8.2"
 "react-dom": "16.8.2"
 

Ниже приведен минимальный пример кода:

A. tsx

 const root_store = new RootStore();

ReactDOM.render(
    <Provider root_store={root_store}>
        <IApp></IApp>
    </Provider>,
    document.getElementById('root'),
);
 

B. tsx (для компонента IApp ^^)

 interface Props {
    root_store?: RootStore;
}

class App extends React.Component<Props> {
    render(): any {    
        return (
            <div>
                 <IEventsEmbedSkin />
            </div>
        )
    }
}


export const IApp = inject(({root_store}:{root_store:RootStore}) => {
    console.log(root_store);
    return {
        root_store: root_store,
    };
})(observer(App))
 

C. tsx (для компонента IEventsEmbedSkin ^^ )

 interface Props {
    root_store?: RootStore;
}

class EventsEmbedSkin extends React.Component<Props> {
    
    render(): JSX.Element {
        return (
            <div></div>
        );
    }
}

export const IEventsEmbedSkin = inject(({root_store}:{root_store:RootStore}) => {
    console.log(root_store);
    return {
        root_store: root_store,
    };
})(observer(EventsEmbedSkin));
 

Если я НЕ ВИЗУАЛИЗИРУЮ IEventsEmbedSkin компонент в файле B. tsx (импортированный из файла C. tsx), в файле B все работает нормально, react реагирует на любое обновление магазина. когда я визуализирую IEventsEmbedSkin компонент (импортированный из файла C. tsx) Я получаю эту ошибку:

Uncaught Invariant Violation: Hooks can only be called inside the body of a function component.

The above error occurred in the component:

Uncaught Invariant Violation: Hooks can only be called inside the body of a function component.

Can anyone help me with what’s going on?

I cannot change my react version.

my stores look like this:

rootstore.tsx

 export class RootStore {
    context_store: ContextStore;
    recording_store: RecordingStore;

    constructor(props: Props) {

        this.context_store = new ContextStore({
            root_store: this,
        }); 

        this.recording_store = new RecordingStore({
            root_store: this,
        });
    }
}
 

контекстный магазин.tsx:

 export class ContextStore {
    root_store: RootStore;
    status: 'pending' | 'error' | 'done' | 'debug' = 'debug';

    constructor(props: Props) {
        this.root_store = props.root_store;    

        makeObservable(
            this,
            {
                status: observable,
                initialise: action,
            },
            {
                autoBind: true,
            },
        );
    }

    public async initialise(): Promise<void> {
        this.status = 'pending';
        try {
            const data = await this.api_store.get_config_and_instance_data();

            runInAction(() => {
                this.status = 'done';
            });
        } catch (e) {
            runInAction(() => {
                this.status = 'error';
            });
        }
    }
}
 

Комментарии:

1. runInAction похоже на государственный крючок. И, как говорится в ошибке, вы можете вызвать хук только внутри функционального компонента.

2. Знаете ли вы, как преобразовать компонент класса в компонент функции?

3. @Энди, спасибо за ваше предложение, я попробую один раз без отвлекающих маневров и вернусь…

4. @Andy версия react, которую я использую, не поддерживает крючки, я не могу использовать функциональные компоненты. Я также не могу обновить версию react, потому что это не зависит от меня

5. Вам следует обсудить в команде вопрос об обновлении, если у вас возникают подобные проблемы.