Mobx 尴尬的案例。如果我 console.log(userStore) 然后它更新组件

Mobx awkward case. if i console.log(userStore) then it updates component

我已经 userStore 管理授权状态。当 firebase auth 成功获取 auth 数据时,userStore actions to change loading 属性.

class userStore {
  constructor() {
    auth.onAuthStateChanged(user => {
      this.login(user)
      this.loadingDone()
    })
  }

  @observable user
  @observable loading = true

  @computed get getUser() {
    return this.user
  }

  @computed get getLoading() {
    if (this.user) {
      return false
    }
    return this.loading
  }

  @action
  login(user) {
    this.user = user
  }

  @action
  logout() {
    this.user = null
  }

  @action
  loadingDone() {
    this.loading = false
    console.log(this.loading)
  }
}

现在我想将 PrivateRoute 组件更改为 userStore.loading 属性。但是没有 console.log(userStore.getLoading) MOBX 不更新组件。

@observer(['userStore'])
class PrivateRoute extends Component {
  render() {
    const { component: Component, userStore } = this.props
    console.log(userStore.getLoading) # <- WHAT HAPPENS HERE?????
    return (
      <Route
        render={props =>
          userStore.getLoading ? (
            <div>getting auth...</div>
          ) : userStore.getUser ? (
            <Component {...props} />
          ) : (
            <Redirect
              to={{
                pathname: '/login',
                state: { from: props.location }
              }}
            />
          )
        }
      />
    )
  }
}

我无法理解 Mobx 的默认行为。是否取决于console.log

Mobx 根据您在组件中使用的 属性 检测组件更改。

当你 console.log(userStore.getLoading) 时,mobx 知道你的组件依赖于它,当它改变时加载并重新渲染你的组件。

在下面的路由中使用 userStore.getLoading 不算在内(可能是因为它被定义在不同的功能组件中)。 This article may help.

要实现这一点,您可以将 Route 中的组件拆分为一个单独的组件,并为其赋予观察者标签。