在mobx观察者改变后反应不再重新

时间:2017-10-01 13:49:37

标签: reactjs mobx mobx-react

页面加载后,我看到" hi2" 当我点击按钮时,没有任何反应。我也试过了setUser

我怀疑我只是自己编辑道具,不知道是不会触发可观察物?

在全新的rails / react环境中查看它的示例代码:https://github.com/bufordtaylor/mobxtest

  1. 克隆
  2. rails s
  3. (在另一个过程中)./ bin / webpack-dev-server --host 127.0.0.1
  4. 导航至localhost:3000
  5. ======================

    更新:

    我已将其缩减为基本格式,消除了可能的导入错误,提供程序错误或构造函数错误。

    这是

    import React from 'react'
    import ReactDOM from 'react-dom'
    import { observable, action, computed } from 'mobx';
    import { Provider, inject, observer } from 'mobx-react';
    
    
    class UserStore {
    
      @action setUser(val) {
        console.log(val);
        this.user = val;
      }
    
      @observable user = "default";
    }
    
    const userStore = new UserStore();
    
    @observer
    class Hello extends React.Component {
      render() {
        return (
          <div>
            hi2 {this.props.userStore.user}
            <button onClick={this.props.userStore.setUser.bind(this,"fwefwe")}>faew</button>
          </div>
        )
      }
    }
    
    document.addEventListener('DOMContentLoaded', () => {
      ReactDOM.render(
        <Hello userStore={userStore} />,
        document.getElementById('app'),
      )
    })
    

7 个答案:

答案 0 :(得分:4)

我的问题是包装组件的顺序,因为我使用的是Material UI框架。

<强>错误

export inject('store')(observer(withStyles(styles)(MyComponent)));

<强>正确

export withStyles(styles)(inject('store')(observer(MyComponent)));

因此, MobX React Material UI 的订单非常重要。

答案 1 :(得分:2)

您的代码看起来很合理。我认为您偶然发现了文档How to (not) use decorators部分讨论的问题。重要的是transform-decorators-legacy在babel插件列表中排在第一位。

答案 2 :(得分:1)

<button onClick={this.props.userStore.setUser.bind(this,"fwefwe")}>faew</button>

小心点。你绑定this。在这种情况下,This是Hello组件的实例。现在setUser函数中的this指向Hello组件。因此setUser将在Hello Component中设置属性用户。

 @action setUser(val) {
    console.log(val);
    this.user = val; // This this now points to the Hello Component.
  }

要理解我的意思,您可以在setUser方法上设置断点,然后检查变量this。您将看到它指向Hello组件而不是您的商店实例。

而是执行以下操作:

<button onClick={() => { this.props.userStore.setUser("fwefwe"); }}>faew</button>

这里我创建了一个在用户存储上调用setUser的lambda。 因为我在这里使用lambda,this中的this.props.userStore指向Hello组件。

答案 3 :(得分:1)

如果使用最新版本的mobx和babel版本7.12 将此添加到您的构造函数中

makeObservable(this)

答案 4 :(得分:0)

我有类似的问题,我在渲染方法中使用了箭头功能:

render = (): React.ReactNode

正确的应该是:

render(): React.ReactNode

仍然不确定为什么第一种情况会混淆mobx。

答案 5 :(得分:0)

对于到达这里的任何人,请确保您不是像我一样的白痴,并且不要忘记在类组件之前添加@observer装饰器。

(或商店中的@observable装饰器)

上帝,为此浪费了一整天

答案 6 :(得分:0)

我确信造成这种情况的原因有多种。

就我而言,我没有使用装饰器。我只是在我的 mobx 状态对象的构造函数中使用了 makeAutoObservable(this)。我的组件没有在状态更改时重新渲染的原因是因为我没有将默认值应用于 state 属性。

我有一个这样定义的属性:

showModalForIssue: IssueTreeNode;

我有一个 observer 组件正在使用此属性,但未在更改其值时重新呈现。

经过反复讨论后,我最终通过简单地在其定义中应用默认值(将其设置为 null)来修复它,如下所示:

showModalForIssue: IssueTreeNode = null;

这一定与 makeAutoObservable(this) 的工作方式有关。