mobx中的inject,obrver迁移⾄reactHooks写法
1、⽼的⽤法
mobx是⼀个使⽤⼗分普遍的状态管理⼯具,在实际的开发过程中我们常常搭配react进⾏使⽤。在⼀些⽐较⼤的项⽬中,部分变量需要反复向下层组件进⾏传递,如果使⽤传统的组件props进⾏实现,层层包裹,未免过于繁琐,react官⽅针对这种场景,推出了context来进⾏上下⽂跨组件传递。⽽mobx也⽴⾜于react的context实现了inject语法,通过简洁的api,可以在任何想要使⽤全局状态的地⽅注⼊变量。为了⽅便进⾏全局的状态管理,往往设定⼀个全局的store,其中定义⼀些全局都会使⽤到的变量,进⾏状态控制,⽐较典型的例⼦如下:
import React from 'react';
import { inject, obrver } from 'mobx-react';
import comA from 'comA ';
import comB from 'comB';
@inject('globalStore')
@obrver
面皮怎么做
class Test extends React.Component{
render() {
const PanelContent = {
'comA': comA,
'comB': comB
}
const ShowContent = PanelContent[this.props.globalStore.funcType];
return (
<React.Fragment>
<ShowContent />
</React.Fragment>
)
}
}
export default Test ;
如何批改作文这⾥使⽤decorator装饰器语法,通过字符串的⽅式注⼊全局store,组件的this上将会添加属性globalStore,通过store中的funcType的变量来控制显⽰的组件,该变量变化时,渲染的组件也会根据条件变化(通过obrver装饰器实现)。其外围容器的写法通常如下:
import React from 'react';
import { Provider, obrver } from 'mobx-react';
import Test from 'Text';
桂林适合几月份去旅游import globalStorefrom './globalStore';
class parentCom extends React.Component {
const Store = new globalStore({ funcType: 'comA'});
return (
<Provider globalStore={Store}>
<Test />
</Provider>
)
};
export default parentCom;
其⽗组件通过mobx-react的provider包裹器来将全局的store作为参数传⼊。哪怕嵌套多层,⼦组件也可直接通过添加inject装饰器来使⽤全局store中的变量,就如Test。
2、hooks中的inject
react在最新的16.8中启⽤了hooks语法,⼒推函数式组件,尽管官⽅表⽰class式的组件在后续版本中并不会废弃,但是hooks是未来前端框架中组件的发展⽅向(最新的Vue也借鉴了react Hook的很多思路),我们需要⼤胆尝试新鲜事物。
到mobx官⽹上发现,⼏乎所有的例⼦都是基于class组件来写的,并没有发现跟react hook搭配使⽤的内容。。。最后在⼀个不起眼处,找到了⼀个链接,指向mobx-react的迁移⽂档。官⽅操作如下:
import { MobXProviderContext } from 'mobx-react'
function uStores() {
return React.uContext(MobXProviderContext)
}
⾃⼰定义⼀个react hook,让后就可以在我们⾃⼰的组件中使⽤了:
function uUrData() {
const { ur, order } = uStores()
return {
urname: ur.name,
orderId: order.id,
}
}
const UrOrderInfo = obrver(() => {
// Do not destructure data!
const data = uUrData()
return (
<div>
{data.urname} has order {derId}
孔雀开屏鱼
</div>
)
})
从官⽅例⼦中,我们可以发现可以弃⽤inject语法糖,直接通过⾃定义的uStores,我们就可以实现获取外层provider的变量并且使⽤,注意此处不能使⽤解构赋值,否则的话会导致⽆法实现变量的观测(即变量改变,页⾯显⽰没有同步),如果要实现观测:
// u mobx-react@6.1.2 or `mobx-react-lite`
import { uObrver } from 'mobx-react'
function uUrData() {
const { ur, order } = uStores()
return uObrver(() => ({
urname: ur.name,
orderId: order.id,
}))
}
const UrOrderInfo = () => {
// this works now just fine
const { urname, orderId } = uUrData()
return (
<div>dns大全
{urname} has order {orderId}
</div>
)
脚软没力气是什么原因引起的}
如果你还是想要⾃⼰⼿动实现inject⽅法,那么官⽅还给了⼀个简单的inject组件实现:
import { MobXProviderContext } from 'mobx-react'
function inject(lector, baComponent) {
const component = ownProps => {
const store = React.uContext(MobXProviderContext)
return uObrver(() => baComponent(lector({ store, ownProps })))
}
component.displayName = baComponent.name
return component
}
回到我们⾃⼰的组件,如果第⼀部分中的组件,要通过函数式组件的⽅式,使⽤provider提供的全局store要怎么办呢?
import React from 'react';
import { obrver } from 'mobx-react';
import comA from 'comA ';
import comB from 'comB';
import { uStores } from '@utils/index';
function uStores(name) {
return React.uContext(MobXProviderContext)[name];
}
const Test = () => {
3d电影原理
const store = uStores('flagStore'); // ⼿动传⼊字符串,选择要使⽤的内容 const PanelContent = {
'comA': comA,
'comB': comB
}
const ShowContent = PanelContent[store.funcType];
return (
<React.Fragment>
<ShowContent />
如何管理时间</React.Fragment>
)
}
export default obrver(Test );