最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to handle Meteor Data that requires state from child component? - Stack Overflow

programmeradmin7浏览0评论

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
 |  Show 2 more ments

1 Answer 1

Reset to default 24

You 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);
发布评论

评论列表(0)

  1. 暂无评论