1、没有封装成observer
组件
容器组件
import Change from './Change';
import Father from './Father';
const Main = (props: any) => {
return (
<div>
<Father></Father>
<Change></Change>
</div>
)
}
export default Main;
Father组件
import { inject } from 'mobx-react';
import React from 'react';
import Store from '../../store/store';
interface IProps {
store?: Store;
}
const Father = (props: IProps) => {
const { store } = props;
const { message } = store as Store;
return <div>
<div>title: {message.title}</div>
<div>author: {message.author.name}</div>
<div>likes: {message.likes[0]}</div>
</div>
}
export default inject('store')(Father);
Change组件
import { Divider } from 'antd';
import { inject, observer } from 'mobx-react';
import React from 'react';
import Store from '../../store/store';
interface IProps {
store?: Store;
}
const Change = (props: IProps) => {
const { store } = props;
const { setName, setTitle, setLikes } = store as Store;
return <div>
<button onClick={() => setTitle('spin')}>扭转title</button>
<button onClick={() => setName('tom')}>扭转name</button>
<button onClick={() => setLikes('john')}>扭转likes</button>
</div>
}
export default inject('store')(observer(Change));
store
import { observable, action } from 'mobx';
class Store {
@observable message = {
title: 'Bar',
author: {
name: 'Susan'
},
likes: ['Michel']
}
@action
setTitle = (title: string) => {
this.message.title = title;
}
@action
setName = (name: string) => {
this.message.author.name = name;
}
@action
setLikes = (target: string) => {
this.message.likes[0] = target;
}
}
export default Store;
当点击扭转title、name、likes按钮时,store中察看对象message的属性值扭转了,然而Father组件并没有从新渲染。因为Father组件并不是observer组件,只有封装成observer组件,mobx才会对render函数(函数组件了解为return返回的ReactNode)中读取现存的可察看属性做出反馈。
因而,只须要将Father组件封装成observer组件就能够解决
export default inject('store')(Father);
改后
export default inject('store')(observer(Father));
2、MobX 只会为数据是间接通过 render
存取的 observer
组件进行数据追踪
Father组件
const Father = (props: IProps) => {
const { store } = props;
const { message } = store as Store;
return <div>
<div>title: {message.title}</div>
<Child title={() => <div>{message.author.name}</div>}></Child>
<div>likes: {message.likes[0]}</div>
</div>
}
export default inject('store')(observer(Father));
Child组件
interface IProps {
title: () => React.ReactNode;
}
const Child = (props: IProps) => {
const { title } = props;
return <div>{title()}</div>
}
export default Child;
当扭转store中message.author.name时,页面并不会从新渲染。因为div实际上不是由 Father
(有追踪的渲染) 渲染的,而是 Child
。 所以要确保 Child
的 title 能够正确对新的 message.author.name
作出反应,Child
应该也是一个 observer
。
如果 Child
来源于内部库的话,这通常不在你的掌控之中。在这种场景下,你能够用本人的无状态 observer
组件来包裹 div
解决此问题,或通过利用 <Observer>
组件:
// 将Child改成observer组件
const Child = (props: IProps) => {
const { title } = props;
return <div>{title()}</div>
}
export default observer(Child);
另外一种办法能够应用 mobx-react 内置的 Observer
组件,它不承受参数,只须要单个的 render 函数作为子节点:
const Father = (props: IProps) => {
const { store } = props;
const { message } = store as Store;
return <div>
<div>title: {message.title}</div>
<Child title={() => <Observer>{() => <div>{message.author.name}</div>}</Observer>}></Child>
<div>likes: {message.likes[0]}</div>
</div>
}
发表回复