我正在尝试为基于mobx的反应编写单元测试。出于某种原因,当<script>
$( function() {
$( "#divID" ).resizable();
} );
</script>`
中的@observable
值更新时,@action
函数不会像您期望的那样重新运行。
代码:
商品
@computed
COMPONENT 1
class NameStore {
@observable name;
@action setName(name) {
this.name = name;
}
}
COMPONENT 2
@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>
);
}
}
TEST
@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>
);
}
}
出于某种原因,在测试中,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")
});
});
中{this.name}
的实际值保持不变,即使我能够验证商店中的Component1
函数是否被调用正确并具有正确的价值。
关于为什么setName
不重新渲染的任何帮助都将非常感激。
此外,这是一个人为的例子,因为实际的例子是专有的..如果这个例子感到愚蠢,请原谅我:)
谢谢!
答案 0 :(得分:1)
错误很少:
React.Component
@computed
应该在商店input
应绑定到onChange
并更新其value
input
值未定义。最好将其设置为空字符串。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;
额外注意:由于使用了箭头功能,我不必致电.bind(this)
。