【发布时间】:2021-04-13 14:10:03
【问题描述】:
我在从 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;
【问题讨论】:
-
你为什么混合
makeObservable和装饰器?这是使用 mobx 的两种不同方式。 -
@IvanV。对不起,但你错了。 mobx.js.org/…,第 2 页,引用:
Leave all the decorators and call makeObservable(this) in the constructor. This will pick up the metadata generated by the decorators. This is the recommended way if you want to limit the impact of a MobX 6 migration. -
哦,我不知道
decorators andmakeAutoObservable`的选项存在。
标签: reactjs typescript mobx