javascript - 是否可以在 JS 类的构造函数中调用获取初始数据的异步函数?

标签 javascript reactjs typescript mobx

我正在使用 Mobx 和 Mobx React Lite 构建一个示例应用程序,以了解如何使用这个状态管理库。当用户访问页面时,应用程序需要加载问题。像这样在构造函数中调用数据的初始加载可以吗?这会以某种方式导致错误吗?

我担心它可能会再次获取,但我不确定这可能是我应该担心的唯一问题。

如果存在风险,您会建议什么其他模式?

我的另一个想法是,当他们单击“开始测验”按钮时,断章取义,并在获取数据时显示一个加载屏幕。这很可能是应该发生的,但我或多或少只是想知道我所做的是否也很好。

import { observable, action } from "mobx";
import { getQuestions } from "../api/api";

export interface Question {
    category: string;
    type: string;
    question: string;
    correct_answer: string;
    incorrect_answers: string[];
}

export class TriviaStore {

    constructor() {
        // Is this bad?
        (async() => {
            await this.loadQuestions();
        })()
    }

    @observable questions: Question[] = [];
    @observable currentQuestion: number = 0;

    @action
    async loadQuestions() {
        let questions: Question[] = await getQuestions();
        this.questions = questions;
    }
    @action
    nextQuestion() {
        this.currentQuestion++;
    }
}

商店仅在上下文提供程序中实例化一次,如下所示:

import React from 'react';
import { TriviaStore } from '../stores/TriviaStore';

/**
 * Store Types.
 * Add any new stores here so the context type is updated.
 */
type RootStateContextValue = {
    triviaStore: TriviaStore;
}

const RootStateContext = React.createContext<RootStateContextValue>({} as RootStateContextValue);

/**
 * Stores
 * Use this area to create instances of stores to pass down.
 */
const triviaStore = new TriviaStore();

/**
 * Root State Provider
 * @returns global state context wrapper.
 */
export const RootStateProvider: React.FC<React.PropsWithChildren<{}>> = ({children}) => {
    // Finally pass new stores into the object below to send them to global state.
    return (
        <RootStateContext.Provider
            value={{
                triviaStore,
            }}
        >
            {children}
        </RootStateContext.Provider>
    );
}

export const useGlobalState = () => React.useContext(RootStateContext);

最佳答案

我认为在加载所有数据之前初始化存储就可以了。您可以将加载状态直接添加到商店。将异步函数作为方法放在存储上是一个好主意。尽管我认为立即执行的异步函数包装器没有任何效果,并且存储将在加载问题之前初始化。请参阅此示例:

@observable loading = true

constructor() {
  // Same as with your wrapper, constructor cannot be made async.
  this.loadQuestions()
}

@action
async loadQuestions() {
  let questions: Question[] = await getQuestions()
  // Newer versions of MobX will warn if runInAction missing after async call.
  runInAction(() => {
    this.questions = questions
    this.lading = false
  })
}

我认为不太好的部分是将 MobX 存储与 React Context 混合在一起,我认为这是没有必要的,因为您可以直接从任何地方导入存储。

关于javascript - 是否可以在 JS 类的构造函数中调用获取初始数据的异步函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68628026/

相关文章:

javascript - 如何使用 Javascript AJAX 请求(无 jQuery)仅获取文件的一部分

javascript - 如何检测浏览器对 itms 链接的支持?

node.js - 在 VS 代码中调试由 Electron 生成的子进程

javascript - 调用函数对象来加载你的js

javascript - React + Redux HOC 加载器

javascript - 如何在部分输入中创建拆分?

html - 在 Angular 2 中按表单编辑值

javascript - 如何使用键值对象作为 Angular Material 表的数据源

javascript - 为什么我的对象中的数据没有设置到我的 React 类组件中的 setState

javascript - 将 Express 连接到 React webpack 项目