跨组件交互
在不使用其它框架、类库的情况下,React要实现跨组件交互这一功能相对有些繁琐。通常我们需要在父组件上定义一个state和一个修改该state的函数。然后把state和这个函数分别传到两个子组件里,在逻辑简单,且子组件很少的时候可能还好,但当业务复杂起来后,这么写就非常繁琐,且难以维护。而用Mobx就可以很好地解决这个问题。来看看以下的例子:
class MyState {
@observable num1 = 0;
@observable num2 = 100;
@action addNum1 = () => {
this.num1 ++;
};
@action addNum2 = () => {
this.num2 ++;
};
@computed get total() {
return this.num1 + this.num2;
}
}
const newState = new MyState();
const AllNum = observer((props) => <div>num1 + num2 = {props.store.total}</div>);
const Main = observer((props) => (
<div>
<p>num1 = {props.store.num1}</p>
<p>num2 = {props.store.num2}</p>
<div>
<button onClick={props.store.addNum1}>num1 + 1</button>
<button onClick={props.store.addNum2}>num2 + 1</button>
</div>
</div>
));
@observer
export default class App extends React.Component {
render() {
return (
<div>
<Main store={newState} />
<AllNum store={newState} />
</div>
);
}
}
有两个子组件,Main和AllNum (均采用无状态函数的方式声明的组件)
在MyState中存放了这些组件要用到的所有状态和函数。
之后只要在父组件需要的地方实例化一个MyState对象,需要用到数据的子组件,只需要将这个实例化的对象通过props传下去就好了。
那如果组件树比较深怎么办呢?
我们可以借助React15版本的新特性context
来完成。它可以将父组件中的值传递到任意层级深度的子组件中。--详情可以查看React的官方文档https://reactjs.org/docs/context.html
接下来看看网络请求的情况。
useStrict(true);
class MyState {
@observable data = null;
@action initData = async() => {
const data = await getData("xxx");
runInAction("说明一下这个action是干什么的。不写也可以", () => {
this.data = data;
})
};
}
严格模式下,只能在action中修改数据,但是action只能影响到函数当前状态下
的情景,也就是说在await之后发生的事情,这个action就修饰不到了,于是我们必须要使用了runInAction(详细解释见上文)。
当然如果你不开启严格模式,不写runInAction也不会报错。
个人强烈建议开启严格模式,这样可以防止数据被任意修改,降低程序的不确定性