Javascript 测试中更新可观察值时,mobx计算函数未重新运行

Javascript 测试中更新可观察值时,mobx计算函数未重新运行,javascript,reactjs,mocha.js,enzyme,mobx,Javascript,Reactjs,Mocha.js,Enzyme,Mobx,我试图为基于mobx的反应编写一个单元测试。出于某种原因,当在@操作中更新@可观察值时,@计算函数不会像您预期的那样重新运行 代码: 商店 class NameStore { @observable name; @action setName(name) { this.name = name; } } 组件1 @observer class Name { @computed get name() { if (this.props

我试图为基于mobx的反应编写一个单元测试。出于某种原因,当在
@操作
中更新
@可观察
值时,
@计算
函数不会像您预期的那样重新运行

代码:

商店

class NameStore {
    @observable name;

    @action setName(name) {
        this.name = name;
    }
}
组件1

@observer
class Name {
    @computed get name() {
        if (this.props.nameStore.name) {
            return `${this.props.nameStore.name} is awesome!`;
        }

        return null;
    }

    render() {
        return (
            <div className="name">
                {this.name}
            </div>
        );
    }
}
@observer
类名{
@计算的获取名称(){
if(this.props.nameStore.name){
return`${this.props.nameStore.name}太棒了!`;
}
返回null;
}
render(){
返回(
{this.name}
);
}
}
组件2

@observer
class Name {
    setName() {
        this.props.nameStore.setName(this.name);
    }

    render() {
        return (
            <form onSubmit={this.setName.bind(this)}>
                <input type="text" ref={input => this.name = input} />
            </form>
        );
    }
}
@observer
类名{
setName(){
this.props.nameStore.setName(this.name);
}
render(){
返回(
this.name=input}/>
);
}
}
测试

define('Name component', () => {
    let markup;

    beforeEach(() => {
        const nameStore = new NameStore();
        markup = mount(
            <div>
                <Component1 nameStore={nameStore} />
                <Component2 nameStore={nameStore} />
            </div>
        );
    });

    it('should re-render name when updated', (done) => {
        expect(markup.find('.name').text()).to.be.blank;

        markup.find('form input').first().value = "john";
        markup.find('form').simulate('submit');

        expect(markup.find('.name').text()).to.equal("john is awesome")
    });
});
define('Name component',()=>{
让标记;
在每个之前(()=>{
const nameStore=新名称存储();
标记=装载(
);
});
它('更新时应重新呈现名称',(完成)=>{
expect(markup.find('.name').text()).to.be.blank;
markup.find('form input').first().value=“john”;
markup.find('form').simulate('submit');
expect(markup.find('.name').text()).to.equal(“john很棒”)
});
});
出于某种原因,在测试中,
Component1
中的
{this.name}
的实际值保持不变,即使我能够验证是否正确调用了存储中的
setName
函数并使用了正确的值

对于
Component1
未重新渲染的原因,如有任何帮助,将不胜感激

此外,这是一个人为的例子,因为实际的例子是专有的。所以请原谅我,如果这个例子觉得愚蠢:)


谢谢

错误很少:

  • 两个组件均未扩展
    React.Component
  • @computed
    应该在商店中
  • input
    应绑定到
    onChange
    并更新其
  • 浏览器可能会抱怨
    输入
    值未定义。最好将其设置为空字符串
  • input
    值位于
    event.target.value
    ref={input=>this.name=input}
    this.name
    分配给html组件
  • 处理表单时的经验法则是调用
    event.preventDefault()
下面的代码是基于您的代码的完整工作示例:

import React from 'react';
import { observable, action, computed } from 'mobx';
import { observer } from 'mobx-react';

class NameStore {
  @observable name = '';

  @action
  setName = name => {
    this.name = name;
  }

  @computed
  get awesomeName() {
    return this.name ? `${this.name} is awesome!` : '';
  }
}

@observer
class NameField extends React.Component {
  render() {
    const { nameStore } = this.props;
    return <div className="name"> {nameStore.awesomeName} </div>;
  }
}

@observer
class NameInput extends React.Component {
  render() {
    const { nameStore } = this.props;
    return (
      <form>
        <input
          type="text"
          onChange={this.onChange}
          value={nameStore.name}
        />
      </form>
    );
  }

  onChange = e => {
    const { nameStore } = this.props;
    nameStore.setName(e.target.value);
    e.preventDefault();
  }
}

@observer
class App extends React.Component {
  nameStore = new NameStore();

  render() {
    return (
      <div>
        <NameField nameStore={this.nameStore} />
        <NameInput nameStore={this.nameStore} />
      </div>
    );
  }
}

export default App;
从“React”导入React;
从“mobx”导入{可观察、操作、计算};
从'mobx react'导入{observer};
类名称存储{
@可观察名称=“”;
@行动
setName=name=>{
this.name=名称;
}
@计算
获取awesomeName(){
返回this.name?`${this.name}太棒了!`:'';
}
}
@观察者
类名称字段扩展了React.Component{
render(){
const{nameStore}=this.props;
返回{nameStore.awesomeName};
}
}
@观察者
类NameInput扩展了React.Component{
render(){
const{nameStore}=this.props;
返回(
);
}
onChange=e=>{
const{nameStore}=this.props;
nameStore.setName(例如target.value);
e、 预防默认值();
}
}
@观察者
类应用程序扩展了React.Component{
名称存储=新名称存储();
render(){
返回(
);
}
}
导出默认应用程序;
额外注意:由于使用了arrow函数,我不必调用
.bind(this)