【问题标题】:Meteor handle.ready() in render() not triggering rerender of component渲染()中的流星handle.ready()不会触发组件的重新渲染
【发布时间】:2017-03-14 11:53:31
【问题描述】:

我的渲染方法中有以下代码:

 render() {
    return (
        <div>
                {this.props.spatulaReady.ready() ? <p>{this.props.spatula.name}</p> : <p>loading spatula</p>}
        </div>
    )
}

根据我的理解,检查订阅句柄是否准备好(数据在那里)并显示它。如果没有数据可用,它应该显示一个简单的加载消息。但是,当我第一次加载这个 sn-p 所在的页面时,它卡在了加载部分。在页面重新加载数据(通常)显示正常。

如果我在页面第一次加载时检查 spatulaReady.ready() 并且当显示卡在“正在加载抹刀”时,以及应该在那里的数据,句柄报告为准备好并且数据就在那里应该是。如果我刷新页面,它也显示得很好。问题是,这种检查数据并在数据到达时进行渲染的方式在过去对我来说效果很好。是因为渲染方法不是反应式的吗?因为 handle.ready() 应该是反应式的。

更奇怪的是,它有时会在页面加载时正确显示数据,似乎是随机的。

创建容器代码:

export default createContainer(props => {
    return {
        user: Meteor.user(),
        spatulaReady: Meteor.subscribe('spatula.byId', props.deviceId),
        spatula: SpatulaCollection.findOne()
    }
}, SpatulaConfig)

发布代码:

Meteor.publish('spatula.byId', function(deviceId) {
    const ERROR_MESSAGE = 'Error while obtaining spatula by id'

    if (!this.userId) //Check for login
        throw new Meteor.Error('Subscription denied!')
    const spatula = SpatulaCollection.findOne({_id: deviceId})
    if(!spatula) //No spatula by this id
        throw new Meteor.Error(403, ERROR_MESSAGE)
    if(spatula.ownedBy != this.userId) //Spatula does not belong to this user
        throw new Meteor.Error(403, ERROR_MESSAGE)

    return SpatulaCollection.find({_id: deviceId})

})

我知道我在这里遗漏了一块拼图,但我一直没有找到它。如果您不知道我的具体问题的解决方案,请以另一种等待数据到达再显示数据的方式为我指明正确的方向。

编辑:经过反复试验并阅读了与我的项目相关的各种其他帖子后,我找到了解决方案:

export default createContainer(props => {
    const sHandle= Meteor.subscribe('spatula.byId', props.deviceId)
    return {
        user: Meteor.user(),
        spatulaReady: sHandle.ready(),
        spatula: SpatulaCollection.findOne()
    }
}, SpatulaConfig)

移动 ready() 调用来创建容器解决了我的所有问题,这对我来说仍然没有意义。

【问题讨论】:

  • 尝试将.ready() 调用放入容器中。我认为这与反应性有关。

标签: reactjs meteor collections


【解决方案1】:

如您所见,将.ready() 调用移至createContainer 可以解决问题。这是因为 Meteor 反应性仅在您调用 反应性数据源(反应性函数)时起作用,例如 反应性上下文 中的 collection.find() 或 subscriptionHandle.ready(),例如Tracker.autorun 或 createContainer。从 Meteor 的角度来看,React 组件中的函数(包括 render)不是反应式上下文。

请注意,React 和 Meteor 反应性是两个不同的东西。 React 的反应性很简单,所以每当组件的 props 或 state 发生变化时,它的 render 函数就会重新运行。它对 Meteor 的反应式数据源一无所知。由于createContainer(当其中的反应性数据源发生变化时由 Meteor 反应性重新运行)只是将道具传递给底层组件,因此当从 @ 给出的道具时,该组件由 React 重新渲染987654332@更改。

【讨论】:

    猜你喜欢
    • 2020-08-18
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-02
    • 2020-02-13
    • 2021-06-20
    • 2017-06-09
    相关资源
    最近更新 更多