Switching some code over in Meteor 1.3 to ES6+ React syntax. Component requires getting Meteor data, so I'm using a createComponent to replace getMeteorData(). The problem is, the old getMeteorData used state from the ponent, which isn't being accessed by the createContainer ponent.
Old code:
Component = React.createClass({
mixins: [ReactMeteorData],
getMeteorData() {
var mo = this.state.currentMonth;
var start = newDate(moment(mo).startOf('month'));
return {
events: collections.events.find({
$or: qwry,
startDate: { $gte: start },
endDate: { $lte: end }
}).fetch(),
}
},
render() {
...
}
});
New Code Thus Far
class Component = React.Component {
constructor(props) {
super(props);
}
render() {
...
}
}
export default createContainer(({params}) => {
var mo = this.state.currentMonth;
var start = newDate(moment(mo).startOf('month'));
return {
events: collections.events.find({
$or: qwry,
startDate: { $gte: start },
endDate: { $lte: end }
}).fetch(),
}
}, Component);
Getting the error "cannot get currentMonth of undefined," since it's trying to access state. Any suggestions?
Switching some code over in Meteor 1.3 to ES6+ React syntax. Component requires getting Meteor data, so I'm using a createComponent to replace getMeteorData(). The problem is, the old getMeteorData used state from the ponent, which isn't being accessed by the createContainer ponent.
Old code:
Component = React.createClass({
mixins: [ReactMeteorData],
getMeteorData() {
var mo = this.state.currentMonth;
var start = newDate(moment(mo).startOf('month'));
return {
events: collections.events.find({
$or: qwry,
startDate: { $gte: start },
endDate: { $lte: end }
}).fetch(),
}
},
render() {
...
}
});
New Code Thus Far
class Component = React.Component {
constructor(props) {
super(props);
}
render() {
...
}
}
export default createContainer(({params}) => {
var mo = this.state.currentMonth;
var start = newDate(moment(mo).startOf('month'));
return {
events: collections.events.find({
$or: qwry,
startDate: { $gte: start },
endDate: { $lte: end }
}).fetch(),
}
}, Component);
Getting the error "cannot get currentMonth of undefined," since it's trying to access state. Any suggestions?
Share Improve this question asked Apr 5, 2016 at 19:01 ebrillhartebrillhart 1231 silver badge5 bronze badges 7- Try not to send it from child to parent, it should be the other way around, parent holds the state of the children and passes it down as props... react docs on multiple ponents : In React, data flows from owner to owned ponent through props: facebook.github.io/react/docs/multiple-ponents.html – omarjmh Commented Apr 5, 2016 at 20:28
- yeah, I realize that, but I'm trying to figure out the best way to convert over to the new format based on the way it was being handled before. just trying to figure out if I need to pletely rework the way we're getting the "mo" variable in the current code or if there's some sort of workaround for ponents that previously used the ponent's state in getMeteorData. – ebrillhart Commented Apr 5, 2016 at 20:58
- why can't you just put the getMeteorData function inside of the react.Component? thats fine to do – omarjmh Commented Apr 5, 2016 at 21:03
- check out this blog posthttp://www.newmediacampaigns./blog/refactoring-react-ponents-to-es6-classes I hope this is what you're talking about...I'm still not 100% sure – omarjmh Commented Apr 5, 2016 at 21:04
- thanks for the resources! I think the issue is kind of specific to using React and Meteor in conjunction with each other. you can't really use the mixins with the React.Component element, which means that getMeteorData() doesn't work the way it should. might just be something we need to puzzle through a bit more on our own, since we haven't been able to e up with or find a decent solution so far. – ebrillhart Commented Apr 5, 2016 at 21:36
1 Answer
Reset to default 24You can split the old ponent into two partial ponents: one that holds the state and handles events, and a pure one that merely displays results. Make sure to pass event handlers as callbacks to the child ponent. Also note how the parent ponent uses the return value of the createContainer()
function.
// Parent ponent, setState should go here
export default class StateHolder extends React.Component {
constructor(params) {
super(params);
this.state = {myKey: 1};
}
incrementKey() {
this.setState({myKey: this.state.myKey + 1});
}
render() {
return <Container myKey={this.state.myKey} onClick={this.incrementKey.bind(this)} />;
}
}
// Child ponent, renders only
class PureComponent extends React.Component {
render() {
return <div>
{this.props.myValue}
<button onClick={this.props.onClick}>click me</button>
</div>;
}
}
// Decorated child container.
// Make sure to use this one in parent ponent's render() function!
let Container = createContainer((props) => {
let doc = MyCollection.findOne({someKey: props.myKey});
return {
myValue: doc ? doc.someValue : null
}
}, PureComponent);