迁移到 Mobx 6:功能组件不能与修饰的 observable 一起工作

问题描述

我在从 Mobx 4 迁移到 Mobx 6 时遇到了问题。

我有一个功能组件,但在更新 Mobx 后它停止工作。看来商店不行。组件通过 reaction 功能对可观察变量内的更改做出反应,但不会重新呈现更改。我制作了 migration guide 中提供的所有内容,但组件的商店不起作用。

出于某种原因,如果我将功能组件更改为类组件,一切都会开始工作。但我真的不明白为什么会发生这种情况,也找不到对这种行为的任何解释。

案例看起来像下面的例子。启用了实验性装饰器以及迁移指南中提供的任何其他内容。那么这种行为的原因是什么,我如何在功能组件中实现正确逻辑?

interface User {
  name: string;
  age: number;
  info: {
    phone: string;
    email: string;
  };
}

const usersData: User[] = [
  {
    name: "Steve",age: 29,info: {
      phone: "+79011054333",email: "steve1991@gmail.com",},{
    name: "George",age: 34,info: {
      phone: "+79283030322",email: "george_the_best_777@gmail.com",{
    name: "Roger",age: 17,info: {
      phone: "+79034451202",email: "rodge_pirat_yohoho@gmail.com",{
    name: "Maria",age: 22,info: {
      phone: "+79020114849",email: "bunnyrabbit013@gmail.com",];

const getUsers = () => {
  return new Promise<User[]>((resolve) => {
    setTimeout(() => {
      resolve(usersData);
    },2000);
  });
};
class Store {
  @observable users: User[] = [];

  constructor() {
    makeObservable(this);
  }

  async init() {
    const users = await getUsers();
    this.setUsers(users);
  }

  @action setUsers(users: User[]) {
    this.users = users;
  }

  @action increaseUserAge(userIndex: number) {
    const users = this.users.map((u,k) => {
      if (k === userIndex) {
        u.age += 1;
      }
      return u;
    });
    this.setUsers(users);
  }

  @computed get usersCount(): number {
    return this.users.length;
  }
}

const store = new Store();

const UserList = observer(() => {
  React.useEffect(() => {
    store.init();
  },[]);

  const addOneUser = () => {
    const user = {
      name: "Jesica",age: 18,info: {
        phone: "+79886492224",email: "jes3331@gmail.com",};
    store.setUsers([...store.users,user]);
  };

  return (
    <div className="App">
      <h4>Users: {store.usersCount}</h4>
      {store.users.length ? (
        <>
          <ul>
            {store.users.map((user,key) => (
              <li key={key}>
                Name: {user.name},Age: {user.age},Info:
                <div>
                  Phone: {user.info.phone},Email: {user.info.email}
                </div>
                <button onClick={() => store.increaseUserAge(key)}>
                  Increase Age
                </button>
              </li>
            ))}
          </ul>
          <button onClick={addOneUser} disabled={store.usersCount >= 5}>
            Add one user
          </button>
        </>
      ) : (
        <p>Fetching users...</p>
      )}
    </div>
  );
});

function App() {
  return <UserList />;
}

export default App;

解决方法

我已经用您的代码制作了 Codesandbox example(虽然删除了类型),但效果很好。

在那里检查 tsconfig.json,也许您忘记启用某些选项?

或者检查您使用的是什么版本的 mobxmobx-react

只是对如何使用 increaseUserAge 操作的一个小挑剔,就这么简单:

  @action increaseUserAge(user) {
    user.age += 1;
  }

在 jsx 中,您只需将整个用户传递到那里:

<button onClick={() => store.increaseUserAge(user)}>
  Increase Age
</button>