I’m getting myself into a bit of a muddle with React and Meteor. I’m trying to create an update form where the user types into fields and then validation messages are shown below the fields if the data fails validation. Then ultimately the user will press the submit button to save the whole lot to the database.
In my GetMeteorData function I get a customer:
getMeteorData() {
const customerId = () => FlowRouter.getParam('_id');
var handle = Meteor.subscribe('CustomerCompany.get', customerId());
cust = CustomerCompanies.findOne({_id: customerId()});
return {
customerLoading: !handle.ready(),
customer: cust,
errors: {}
};
},
and then in my render() method I pass that customer to my dumb form:
render() {
//console.log("render started")
if (this.data.customerLoading) {
return ( <h3>Loading</h3> );
}
return (
<CustomerEditComponent
customer={this.data.customer}
onChange={this.onChangeHandler}
onSave={this.saveCustomer}
errors={this.data.errors}
/>
);
}
When the user makes a change that’s then handled by this code:
onChangeHandler: function (event) {
// update our customer data to reflect the new value in the UI
var field = event.target.name;
var value = event.target.value;
this.data.customer[field];
// validation logic chopped out for brevity
return this.setState({customer: this.data.customer});
},
and if they save:
saveCustomer(event) {
event.preventDefault();
// how to get data from state to the db?
}
The problem with that however is that typing in the fields on the form does not cause the UI to update. That’s because the render method never gets rerun, and I think I understand that that’s because I’m using this.data.customer
rather than this.state.customer
to populate the form and React isn’t watching for changes to this.data.customer
.
Furthermore, I probably shouldn’t be writing to this.data.customer
anyway as that is the actual database doc, where as all I want to do is update the state so the UI is re-rendered with the users update and any validation is performed.
So, assuming some of that is right, how do I get a version of the customer into the state and update it so that the UI responds, and then how do I get it back to the database once the user submits?
I tried adding this.setState({customer: cust)
into getMeteorData()
, but that just got me this error:
Uncaught Error: Can’t call
setState
insidegetMeteorData
as this could cause an endless loop. To respond to Meteor data changing, consider making this component a “wrapper component” that only fetches data and passes it in as props to a child component. Then you can usecomponentWillReceiveProps
in that child component.
Any help gratefully received!