react 16.8.0
推出hooks
后所有无状态组件都可以使用函数组件的形式编写,非常简洁!
那么,如何某个业务场景需要在函数组件中使用的mobx
,又该如何应用呢?下本为你一一揭晓。
mobx
在类组件常见写法如下:
import React from 'react';
import { inject, oberver } from 'mobx-react';
@inject('xxx')
@observer
class Test extends React.Component {
render() {
return <></>
}
}
export default Test;
使用的是修饰器方式向组件注入store
,我们也可以不使用修饰器方式,改用函数式写法:
import React from 'react';
import { inject, oberver } from 'mobx-react';
class Test extends React.Component {
render() {
return <></>
}
}
export default inject('xxx')(observer(Test));
这两种方式都是同样的效果,另外将inject、observer
两个高阶组件附上:
export declare function inject(...stores: Array<string>): <T extends IReactComponent<any>>(target: T) => T & (T extends IReactComponent<infer P> ? IWrappedComponent<P> : never);
export declare function inject<S, P, I, C>(fn: IStoresToProps<S, P, I, C>): <T extends IReactComponent>(target: T) => T & IWrappedComponent<P>;
export declare function observer<T extends IReactComponent>(component: T): T;
observer
函数接受的组件类型继承IReactComponent
,而IReactComponent
类型的定义如下:
export declare type IReactComponent<P = any> = React.ClassicComponentClass<P> | React.ComponentClass<P> | React.FunctionComponent<P> | React.ForwardRefExoticComponent<P>;
可以看到支持FunctionComponent
函数组件,那么我们能不能使用函数式方式向函数组件注入mobx
呢?
import { inject, observer } from 'mobx-react';
const Test = (props) => {
const { count, setCount } = this.props.countStore;
const add = () => {
setCount(count + 1);
};
return (
<div>
<div>{count}</div>
<button onClick={add}>++++</button>
</div>
)
}
export default inject('countStore')(observer(Test))
本以为一切都很完美,但是运行后报错了
那我们就来分析一下为什么报错了把....
打上几点断点调试后发现,因为上面调用setCount
没有指定调用对象,所以执行到action
时this
指向了undefined
,所以报错了。
既然知道了问题所在,那我们指定this就可以了
const add = () => {
setCount.call(props.countStore, count + 1);
};
补充:为什么函数组件不能使用修饰器写法呢?
这个我觉得没有必要,因为修饰器属于侵入式,inject、observer
属于高阶组件,直接使用入参控制就可以了,而类组件的话就需要外部的侵入。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。