【问题标题】:How to handle Meteor Data that requires state from child component?如何处理需要子组件状态的流星数据?
【发布时间】:2016-07-25 21:33:13
【问题描述】:

将 Meteor 1.3 中的一些代码转换为 ES6+ React 语法。组件需要获取 Meteor 数据,所以我使用 createComponent 来替换 getMeteorData()。问题是,旧的 getMeteorData 使用了组件中的状态,createContainer 组件没有访问该状态。

旧代码:

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() {
   ...
  }
});

到目前为止的新代码

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);

收到错误“无法获取未定义的 currentMonth”,因为它正在尝试访问状态。有什么建议吗?

【问题讨论】:

  • 尽量不要将它从孩子发送到父母,它应该是相反的,父母持有孩子的状态并将其作为道具传递......在多个组件上反应文档:在反应中,数据通过 props 从所有者流向拥有的组件:facebook.github.io/react/docs/multiple-components.html
  • 是的,我意识到这一点,但我正在尝试根据之前的处理方式找出转换为新格式的最佳方式。只是想弄清楚我是否需​​要完全修改我们在当前代码中获取“mo”变量的方式,或者是否有某种解决方法可以解决以前在 getMeteorData 中使用组件状态的组件。
  • 为什么不能把 getMeteorData 函数放在 react.Component 里面?这样做很好
  • 查看这篇博文http://www.newmediacampaigns.com/blog/refactoring-react-components-to-es6-classes 我希望这就是你所说的......我'我仍然不是 100% 确定
  • 感谢您的资源!我认为这个问题是特定于将 React 和 Meteor 结合使用的。您不能真正将 mixins 与 React.Component 元素一起使用,这意味着 getMeteorData() 不能按应有的方式工作。可能只是我们需要自己解决更多问题,因为到目前为止我们还没有想出或找到合适的解决方案。

标签: javascript meteor reactjs


【解决方案1】:

您可以将旧组件拆分为两个部分组件:一个保存状态并处理事件,另一个仅显示结果。确保将事件处理程序作为回调传递给子组件。还要注意父组件如何使用createContainer()函数的返回值。

// Parent component, 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 component, 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 component's render() function!
let Container = createContainer((props) => {
  let doc = MyCollection.findOne({someKey: props.myKey});
  return {
    myValue: doc ? doc.someValue : null
  }
}, PureComponent);

【讨论】:

  • @aedm 非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-29
  • 1970-01-01
  • 2020-12-03
  • 2016-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多