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>}