I’m a little perplexed as to why an input field in a particular component of mine isn’t reactively updating. My app has a contests collection and each contest has it’s own page. I wrap the ContestPage component in a ContestPageContainer component that fetches data and passes it to the ContestPage via props. Here are the two components:
ContestPageContainer
C.ContestPageContainer = React.createClass({
propTypes: {
contest_id: React.PropTypes.string
},
mixins: [
ReactMeteorData
],
getInitialState() {
return {}
},
getMeteorData() {
var contestId = this.props.contest_id;
var handle = Meteor.subscribe("contest", contestId);
return {
contest: Contests.findOne(contestId),
contestLoading: ! handle.ready(),
currentUser: Meteor.user()
};
},
componentWillMount() {
},
componentDidMount() {
},
componentWillReceiveProps() {
},
shouldComponentUpdate() {
return true;
},
componentWillUnmount() {
},
render() {
if (this.data.contestLoading) {
return (
<C.Loading />
);
} else {
return (
<C.ContestPage contest={this.data.contest} contestLoading={this.data.contestLoading} currentUser={this.data.currentUser}/>
)
}
}
});
ContestPage
C.ContestPage = React.createClass({
propTypes: {
contest: React.PropTypes.object,
contestLoading: React.PropTypes.bool,
currentUser: React.PropTypes.object
},
mixins: [],
getInitialState() {
return {
errors: {}
}
},
getMeteorData() {
// return {
// currentUser: Meteor.user()
// };
},
componentWillMount() {
},
componentDidMount() {
},
componentWillReceiveProps() {
},
shouldComponentUpdate() {
return true;
},
componentWillUnmount() {
},
handleSideToggle(e) {
e.preventDefault();
$("#wrapper").toggleClass("toggled");
},
handleOnBlur(e) {
var contestId = this.props.contest._id;
var property = $(e.target).context.name;
var value = $(e.target).val();
var self = this;
var modifier = {
'$set': {
}
};
modifier['$set'][property] = value;
Meteor.call("contests/update", modifier, contestId, function(err) {
if (err) {
alert("Contests Update Error: " + err.reason);
}
});
},
render() {
return (
<div classNameName="contest-page-wrapper">
<div id="wrapper">
<C.ContestPageSidebar />
<div id="page-content-wrapper">
<div className="container-fluid">
<div className="row">
<div className="col-lg-12">
<div>
<div className="page-title">
<h1>{this.props.contest.title}</h1>
</div>
<div className="col-sm-12 visible-xs-block top-right-button text-left">
<a href="#" className="btn btn-primary" id="menu-toggle" onClick={this.handleSideToggle}>Toggle Menu</a>
</div>
</div>
</div>
</div>
<div className="row">
<div className="col-sm-8">
<form id="contest-page">
<C.FormInput hasError={!!this.state.errors.description} name="Description" type="textarea" label="Description" value={this.props.contest.description} onBlur={ this.handleOnBlur }/>
<C.FormInput hasError={!!this.state.errors.prize} name="Prize" type="text" label="Prize" value={this.props.contest.prize} onBlur={ this.handleOnBlur }/>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
)
}
});
If I open two browsers next to each other and update a field (which calls a method and updates the collection) the same field on the other screen doesn’t update. I’m guessing that a form input value property is a special case and I’m going to have to do something special to reactively update it… Is that correct? Or am I doing something wrong?
Also, I am specifically referring to the <C.FormInput />
component in the ContestPage component.