React/Mobx:TypeError:无法读取未定义的属性“地图”

时间:2021-01-11 11:48:37

标签: reactjs typescript api mobx mobx-react

我想做什么;

  • 从 API 中提取数据并将其插入到名为 UserStore 的 mobx 存储中
  • 在另一个组件中检索和显示用户存储数据

这是我的 UserStore.ts

import { observable, action } from 'mobx';
import { getUser } from '../api/api';

export class UserStore {

@observable users: [{
    firstName: string;
    surName: string;
    dateofBirth: string;
    ethnicity: string,
    maritalStatus: string,
}]


@action 
loadUser = () => {
    getUser().then(users => this.users = users)
    console.log(this.users)
}
}

这是我检索 data.ts 的 Api 调用 这个后端 API 在 Visual Studio 上作为一个单独的项目运行,我已经检查过它是否正常工作,并且在通过邮递员请求时能够收到 200 响应。

export const getUser = ():Promise<[{ firstName: string; surName: string; dateofBirth: string; ethnicity: string; maritalStatus: string; }]> => {
return fetch('https://localhost:5001/api/personalInfo/1').then(res => res.json())
} 

这是我的 RootStateContext 这样我就可以在项目的任何地方使用 Store

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

type RootStateContextValue = {
    userStore: UserStore;
};

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

const userStore = new UserStore();

export const RootStateProvider: React.FC<React.PropsWithChildren<{}>> = ({ children }) => {
    return <RootStateContext.Provider value={{ userStore }}> {children} 
</RootStateContext.Provider>;
};

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

这是我的 index.tsx

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import reportWebVitals from './reportWebVitals';
import App from './App';
import { RootStateProvider } from './context/RootStateContext';

import './css/main.css';

ReactDOM.render(
    <BrowserRouter basename={'myCareer'}>
        <RootStateProvider>
            <App />
        </RootStateProvider>
    </BrowserRouter>,
    document.getElementById('root'),
);

这是我的 PersonalInformation_Card.tsx,我试图在其中映射来自 UserStore 的数据并显示它

export default function PersonalInformation_Paper() {
const { userStore } = useRootStore();

return useObserver(() => (
    <>
        <div>
            {userStore.users.map((user) => {
                return (
                    <option key={user.firstName} value={user.firstName}>
                        {user.firstName}
                    </option>
                );
            })}
        </div>
    </>
));
}

在此页面中,我不断收到错误消息;类型错误:无法读取未定义的属性“地图”。我认为这是因为没有执行 API 调用,并且没有填充商店,所以没有什么可映射的,但是我不确定。有人可以帮忙吗?

谢谢

*编辑以按要求显示 console.log(userStore)

enter image description here

*编辑以在更改时显示 console.log(userStore)

    @observable users: [{
    firstName: string;
    surName: string;
    dateofBirth: string;
    ethnicity: string,
    maritalStatus: string,
}]

进入

    @observable users = [{
    firstName: '',
    surName: '',
    dateofBirth: '',
    ethnicity: '',
    maritalStatus: '',
}]

enter image description here

2 个答案:

答案 0 :(得分:0)

试试这个:

  export default function PersonalInformation_Paper() {
        const { userStore } = useRootStore();
        
        return useObserver(() => (
    console.log(userStore)
            <>
                <div>
                    {userStore.users && userStore.users!=undefined ? userStore.users.map((user) => {
                        return (
                            <option key={user.firstName} value={user.firstName}>
                                {user.firstName}
                            </option>
                        );
                    }) : []}
                </div>
            </>
        ));
        

}

答案 1 :(得分:0)

当您初始化 Store users 时,隐式设置为 undefined。即使稍后调用 api,第一次渲染也会因此失败。

你需要用空数组初始化它们或检查它们是否存在:

type User = { firstName: string; surName: string; dateofBirth: string; ethnicity: string, maritalStatus: string, };

export class UserStore {
  // Like that
  @observable users: Array<User> = [];
  
  // ...
}

或检查用户数组是否存在于您的组件中:

export default function PersonalInformation_Paper() {
  const { userStore } = useRootStore();

  return useObserver(() => (
    <> 
      {userStore.users ? 
        <div>
            {userStore.users.map((user) => {
                return (
                    <option key={user.firstName} value={user.firstName}>
                        {user.firstName}
                    </option>
                );
            })}
        </div>
        : 'Loading...'}
    </>
  ));
}