核心概念(与Hook无关)
1. Observable state(可观察的状态)
mobx 可观察的数据
import { observable } from "mobx";
class Todo {
id = Math.random();
@observable title = "";
@observable finished = false;
}
2. 响应式组件
监听 Observable state 并做出响应更新的组件
const TodoView = observer(({todo}) =>
<li>
<input
type="checkbox"
checked={todo.finished}
onClick={() => todo.finished = !todo.finished}
/>{todo.title}
</li>
)
3. Actions(动作)
改变状态(state)的代码
class VarsStore {
@action fetchOrder() {}
}
4. 自动响应 - 参考
- Computed values(计算值)
定义在相关数据发生变化时自动更新的值
class TodoList {
@observable todos = [];
@computed get unfinishedTodoCount() {
return this.todos.filter(todo => !todo.finished).length;
}
}
- autorun
- when
- reaction
Global Stores
全局数据流
1. Store Class
class VarsStore {
// 配置数据
@observable vars = {
isInit: false
} as any
@computed () {}
@action fetchOrder() {}
***
}
2. Context with Stores Instance
import React from 'react'
import FileStore from './mobx-file'
import VarsStore from './mobx-vars'
export const storesContext = React.createContext({
fileStore: new FileStore(),
varsStore: new VarsStore()
})
3. 提供使用 Hook
import { storesContext } from './mobx-store'
export const useStores = () => React.useContext(storesContext)
4. 具体使用
import { useStores } from '@/store/hooks'
export default observer(({ ...args }: any) => {
const { varsStore } = useStores()
*****
})
Hooks
1. useLocalStore - 参考
const localStore = useLocalStore(() => ({
name: "John",
age: 12
}))
2. useAsObservableSource - 参考
它将外部纯(不包含 getter 或 方法)对象转换为 observable 而后在 useLocalStore 对象 get 中进行引用,这样在外部属性改变时自动通知 useLocalStore 对象对变化进行响应
const observableProps = useAsObservableSource(props)
const person = useLocalStore(() => ({
name: "John",
get age () {
return observableProps.age
}
}));
3. useObserver - 参考
包装组件 render 响应数据变化
function Person() {
const person = useLocalStore(() => ({
name: "John",
age: 12
}));
return useObserver(() => (
<div>
<div>姓名:{person.name}</div>
<div>年龄:{person.age}</div>
<button onClick={() => (person.name = "Mike")}>No! I am Mike</button>
</div>
));
}
Hoc
1. observer - 参考
将组件包装为响应式组件,以便在可观察对象的值改变后触发页面的重新渲染。
function Person() {
const person = useLocalStore(() => ({
name: "John",
age: 12
}));
return <div>
<div>姓名:{person.name}</div>
<div>年龄:{person.age}</div>
<button onClick={() => (person.name = "Mike")}>No! I am Mike</button>
</div>
);
}
observer(Person)
Component
1. Observer - 参考
更加细粒度的控制组件的
re-render,特别是针对我们需要传递render props给第三方组件的情形,当render props内使用了observable state,这个时候我们需要使用<Observer>包裹render props的内容
<Observer>{renderFn}</Observer>
使用建议
- 组件的中间使用了
useObserver钩子,它将在可观察到的更改时重新呈现整个组件。如果要微管理渲染,请随时使用<Observer />-- 参考 Observer / useObserver 代码对比
- 自定义复用 useData
import { useObserver } from 'mobx-react'
// 自定义获取接收者数据
function useCustomerData() {
const { currCustomer } = useStores()
return useObserver(() => ({
customerId: currCustomer.customerId,
customerName: currCustomer.customerName,
}))
}
const UserOrderInfo = () => {
// 这里可以这样用
const { customerName, customerId } = useCustomerData()
return (
<div>
{customerName} has order {customerId}
</div>
)
}