Mobx
起步
npm install mobx@6 mobx-react-lite
从一个计数器开始
定义一个计数状态:
import {
observable,
computed,
action,
runInAction,
autorun,
reaction,
when,
} from "mobx";
const initState = {
count: 0,
// computeds
get double() {
return this.count * 2;
},
// actions
increment() {
this.count++;
},
decrement() {
console.log("this:", this);
this.count--;
},
async asyncDecrement() {
await new Promise((resolve, reject) => {
setTimeout(() => {
resolve("yes!");
}, 3000);
});
runInAction(() => {
this.count--;
});
},
};
// observable state
const countStore = observable(initState, {
count: observable,
double: computed,
increment: action,
decrement: action.bound,
asyncDecrement: action,
});
// reactions
autorun(() => {
console.log("countStore.count changed", countStore.count);
});
reaction(
() => countStore.count,
(value, previousValue, reaction) => {
console.log("reaction: 这里执行了一下副作用", value, previousValue);
}
);
when(
() => countStore.count > 3,
() => {
// effect send ajax
console.log("这个值大于3了.");
}
);
export default countStore;
创建一个计数器组件:
import { Button } from "antd";
import { observer } from "mobx-react-lite";
import { countStore } from "../../store";
function Counter(props) {
return (
<div className="counter">
<h2>计数器</h2>
<p>
<Button onClick={() => countStore.decrement()}>-1</Button>
<Button onClick={() => countStore.asyncDecrement()}>async -1</Button>
<span>{countStore.count}, double it: {countStore.double}</span>
<Button onClick={() => countStore.increment()}>+1</Button>
</p>
</div>
);
}
export default observer(Counter);
更加细粒度的更新
创建一个用户信息组件:
import { memo } from "react";
import Base from "./Base";
import Email from "./Email";
function User(props) {
console.log("->User Component render.");
return (
<div className="user-info">
<Base />
<Email />
</div>
);
}
export default memo(User);
创建Base
组件:
// Base
import { observer } from "mobx-react-lite";
import { userStore } from "../../store";
function Base(props) {
console.log("->Base Component render.");
return (
<>
<p>🍎name: {userStore.name}</p>
<p>🍓age: {userStore.age}</p>
</>
);
}
export default observer(Base);
创建Email
组件:
import { observer } from "mobx-react-lite";
import { userStore } from "../../store";
function Email(props) {
console.log("->Email Component render.");
return (
<>
<p>🥝Email: {userStore.email}</p>
</>
);
}
export default observer(Email);
在App组件中引入:
import { useEffect, useState } from "react";
import { Input, Button } from "antd";
import "./App.css";
import User from "./components/User";
import { userStore } from "./store";
function App() {
const [input, setInput] = useState("");
const init = () => {
// fetch userinfo and set
userStore.name = "zhangsan";
userStore.age = 23;
userStore.email = "123456@gmail.com";
};
useEffect(() => {
init();
}, []);
return (
<div className="App">
<User />
<div>
<Input
type="text"
value={input}
onChange={(e) => {
setInput(e.target.value);
}}
/>
<Button
onClick={() => {
userStore.email = input;
}}
>
修改email
</Button>
<Button
onClick={() => {
userStore.name = input;
}}
>
修改name
</Button>
</div>
</div>
);
}
export default App;
于是:
当你修改name的时候,
因此可以借助Mobx实现更细粒度的更新。
更多: