我对流星中的React很新。
TL; DR:在我的数据容器中,更改我的ReactiveVar的值不会重新呈现我的视图。
我有这段代码:
import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import { Meteor } from 'meteor/meteor';
import { createContainer } from 'meteor/react-meteor-data';
// Mail composer - interface for generating enews
class MailComposer extends Component {
constructor(props) {
super(props);
}
handleSubmit( event ) {
event.preventDefault();
const text = this.refs.mailText.value.trim(),
title = this.refs.mailTitle.value.trim(),
rcpts = this.refs.mailRecpts.value.trim();
console.log(text, title, rcpts);
if ( text && title && rcpts ) {
// ...
this.props.hasTestedIt.set( true );
} else {
// ...
}
}
componentDidMount () {
console.log(this);
$( this.refs.textArea ).autosize();
}
getBtnText () {
return ( this.props.hasTestedIt.get() ? "Send it" : "Test it" );
}
render() {
let self = this;
Tracker.autorun(function(){
console.log(self.props.hasTestedIt.get());
});
return (
<div className="panel panel-default panel-primary">
<div className="panel-heading">
<h3 className="panel-title">Mail composer</h3>
</div>
<div className="panel-body">
<form className="form-group" onSubmit={this.handleSubmit.bind(this)}>
<div className="input-group">
<span className="input-group-addon" id="basic-addon1">Title</span>
<input type="text" className="form-control" ref="mailTitle" />
</div>
<br/>
<label htmlFor="js-recipients">Recipients:</label>
<select className="form-control" width="width: initial;" id="js-recipients" ref="mailRecpts">
<option>Admins</option>
<option>All</option>
</select>
<br/>
<label htmlFor="comment">Text:</label>
<textarea className="form-control" rows="5" ref="mailText"></textarea>
<br/>
<button className="btn btn-primary" type="submit">
{this.getBtnText()}
</button>
</form>
</div>
</div>
);
}
}
MailComposer.propTypes = {
hasTestedIt: PropTypes.object.isRequired
};
export default createContainer( () => {
return {
hasTestedIt: new ReactiveVar( false )
};
}, MailComposer);`
但是当我在提交处理程序中设置ReactiveVar
道具时,按钮中getBtnText
方法返回的文本不会更改。我试图将三元组直接放在HTML中,但我得到了相同的结果。
var被正确设置为true,因为autorun正确地记录了更改。
在另一个已复制此组件的组件中,我正确地重新呈现组件,但在.fetch()
上使用find
以renderTasks
方法映射返回的数组它会呈现一个新组件列表。
我错过了什么?我怎么能解决它?
非常感谢!
答案 0 :(得分:2)
组件没有更新,因为传递的hasTestedIt
道具本身没有改变。它改变了它所拥有的价值。
请注意您实际感兴趣的价值。
// Declare the reactive source somewhere appropriately.
const hasTestedIt = new ReactiveVar( false );
// Watch its value instead.
export default createContainer( () => {
return {
hasTestedIt: hasTestedIt.get()
};
}, MailComposer);`
请注意,它现在是传递给MailComposer
的值,而不是ReactiveVar
,可以引用它来更新值。在这种情况下我们如何更新它?
最简单的方法是通过hasTestedIt
和以前一样,虽然这不是我的个人建议。
// Watch its value instead.
export default createContainer( () => {
return {
// Reactive source that triggers re-rendering.
valueOfHasTestedIt: hasTestedIt.get(),
// Provided for the contained component to reference to set new values.
// Leaving this alone doesn't trigger re-rendering!
hasTested
};
}, MailComposer);
这不是优雅的IMO。另一个是将回调函数传递给MailComposer
,可以用来更新值。
const updateHasTestedIt = ( value ) => hasTestedIt.set( value );
// Watch its value instead.
export default createContainer( () => {
return {
hasTestedIt: hasTestedIt.get(),
updateHasTestedIt,
};
}, MailComposer);
class MailComposer extends Component {
...
handleSubmit( event ) {
...
this.props.updateHasTestedIt( true );
...
}
...
};
这次比较好。
可以开发更多,但这实际上取决于您对您的应用程序的偏好。您和只有您才能做出设计决定。