使用 useEffect() 的 Mobx 未在组件中渲染数据

问题描述 投票:0回答:1

我是 React 和 Mobx 新手。

我想通过 useEffect() 中 GET 请求的数据来初始化组件。 有带有 mobx 存储的简单组件:

import { autorun } from "mobx";
import React, { useEffect, useRef } from "react";
import { useStore } from "./store";

const TestPage: React.FC = () => {

    const { testStore } = useStore();
    const isCancelled = useRef(false);

    useEffect(
        () => autorun(
            () => {
            
            const fetchData = async () => {
                const data = await fetch('/api/dictionaries/sources?subject=MATH');
                const json = await data.json();

                if (!isCancelled.current) {
                    testStore.setList(json);
                }
            }

            fetchData().catch(console.error);
            return () => {
                isCancelled.current = true;
            };

        }
        )
        , [testStore, testStore.setList]
    );

    return (
        <div>
            <h1>This is test list</h1>
            {testStore.list.map((i) => <div key={i.id}>{i.id}: {i.name}</div>)}
        </div>
    );
}

export default TestPage;

测试商店.ts:

import { makeAutoObservable } from "mobx";

export interface Item {
    id: string;
    name: string;
}

export default class TestStore {

    list: Item[];
 
    constructor() {
        this.list = [];
        makeAutoObservable(this);
    }

    setList = (list: any) => {
        this.list = list; 
        console.log("In setList: " + this.list);
    }

}

store.tx:

import { createContext, useContext } from "react";
import TestStore from "./test-store";

const store = {
    testStore: new TestStore(),
};

export const StoreContext = createContext(store);

export const useStore = () => {
  return useContext<typeof store>(StoreContext);
};

export default store;

收到服务器的响应,但组件中的列表未渲染:

但是,如果重新编译成热的,组件中的数据就会被渲染。所以我认为问题是异步执行。我可以修复它吗?

reactjs react-hooks mobx mobx-react mobx-react-lite
1个回答
0
投票

为了使 React 组件对 mobX 中的状态变化做出反应,我们需要将组件包装为一个observer(),它是一个 HoC。您可以使用 mobx-reactmobx-react-lite 都可以正常工作。

import { observer } from "mobx-react-lite"
const Component = observer(() => {
   return (
      // JSX Codes that uses mobX states
   )
})

export default Component

不然你也可以这样做

import { observer } from "mobx-react-lite"
    const Component = () => {
       return (
          // JSX Codes that uses mobX states
       )
    }
    
    export default observer(Component)

只有这样,才能触发重新渲染。否则,如果你必须使用 context API,那么我认为你必须使用 useState() 来触发 UI 渲染。

© www.soinside.com 2019 - 2024. All rights reserved.