【问题标题】:Meteor + React: Meteor.subscribe('Collection', limit) Triggers Rerender Every List ElementMeteor + React:Meteor.subscribe('Collection', limit) 触发器重新渲染每个列表元素
【发布时间】:2017-09-22 23:41:55
【问题描述】:

我有一个带有一些设置的 Meteor 订阅,因此我不会发布我的整个集合服务器端。订阅将从meteor/react-meteor-data 中的createContainer() 中获取并显示在一个简单的<ul> 列表中,其中我还将document.id 作为键添加到<li> 元素中。

不幸的是,一旦我增加了订阅第二个订阅参数 (Meteor.subscripte('Collections', settings.limit) 中的 settings.limit,整个 <ul> 列表就会重新呈现?我可以做些什么来增加发布限制,同时只添加新的列表元素?

附:当我通过 Collection.find({}, {limit: newLimit}).fetch() 发布全部 Collection 并更改客户端中的限制时,react 正在按预期工作:保留旧元素并添加新元素!


客户端

import React, { Component } from 'react';
import { Locations } from '/both/collections/locations.js';
import { Events } from '/both/collections/events.js';
import { createContainer } from 'meteor/react-meteor-data';

class Content extends React.Component {
  constructor(props) {
    super(props);
    this.renderLocations = this.renderLocations.bind(this);
  }

  renderLocations() {
    return this.props.locations.map(function(location) {
      return (<li key={location._id} >{location.name}</li>);
    });
  }

  render() {
    console.log(this.props);
    return !this.props.loading && (
      <div>
    <ul>
      {this.renderLocations()}
    </ul>
      <h1 onClick={this.props.increaseLimit}> Limit </h1>
      <div style={{marginBottom: "100px"}}></div>
      </div>
    );
  }
}

export default createContainer((props) => {
  const settings = {
    limit: props.limit,
  }
  const locationsSubscribe = Meteor.subscribe('Locations', settings);
  const loading = !locationsSubscribe.ready();
  if(loading) {
    return { loading };
  } else {
    const _locations = Locations.find({}, {fields: { name: 1}, sort: { name: 1 }}).fetch();

    return {
      loading, 
      locations: _locations,
      increaseLimit: props.increaseLimit,
    };
  }
}, Content);

服务器端

Meteor.publish('Locations', function(settings) {
  return Locations.find({}, {limit: settings.limit, sort: { name: 1} } );
});

Collection.find().fetch() 响应

[
  {
    "name": "3-Master Bike-Style",
    "_id": "N9rWyZMdxEe6jhNW2"
  },
  {
    "name": "43einhalb",
    "_id": "bPgpBm59LohGLaAsf"
  },
  {
    "name": "A&B Döner",
    "_id": "qTNMk73ThvaPxGWqM"
  },
  {
    "name": "A.T.U ",
    "_id": "aWzSmp2zZ8etDhHk6"
  },
  {
    "name": "AIKO Sushibar - Hot Wok",
    "_id": "9pQJgeBNo5gFRkKdF"
  },
  {
    "name": "AXA Stefan Hahn",
    "_id": "d9f6mTrSTGCoeKPbP"
  }
]

【问题讨论】:

  • 您能否分享您在 2 订阅中收集数据的 console.log。可能存在一些逻辑错误。请确保您没有将新数据推送到旧数组。
  • @PankajJatav 你的意思是获取的数组?由 Collection.find().fetch() 返回?
  • 是的,请分享。
  • @PankajJatav 我添加了代码并尝试复制_location 变量
  • 能否也分享一下服务器代码。您的客户端代码看起来不错。

标签: reactjs meteor publish-subscribe


【解决方案1】:

好的,我终于找到了问题: 每次限制更改时,createContainer() 都会再次订阅已发布的集合!这意味着它将新道具发送到我的 Content 组件,这会触发重新渲染!在重新订阅位置数组所需的短时间内,保存为道具的位置数组将被一个空数组覆盖,该数组仅在屏幕上显示为闪光。所以在短时间内不会显示任何内容,然后传输具有正确位置数组的新道具。

解决方案现在将concat() 的新位置数组通过componentWillReceiveProps(nextProps) 转换为Content 组件的状态,只要有新的位置要添加。然后可以比较新旧状态,在shouldComponentUpdate(nextProps, nextState) 内,只在状态变化时更新!

【讨论】:

    【解决方案2】:

    问题在于您的服务器端逻辑。

    您当前的代码:

    Meteor.publish('Locations', function(settings) {
      return Locations.find({}, {limit: settings.limit, sort: { name: 1} } );
    });
    

    这将发送n个文档,基本上你是10、20、30等等文档给客户端。

    修复:您需要跳过上一个文档。

    解决方案:

    Meteor.publish('Locations', function(settings) {
      return Locations.find({}, {skip: settings.skip, limit: settings.limit, sort: { name: 1} } );
    });
    

    或者

    Meteor.publish('Locations', function(settings) {
      var skip = settings.pageNumber * settings.number_of_record_per_page; //change variable according to you
      return Locations.find({}, {skip: settings.limit, limit: settings.limit, sort: { name: 1} } );
    });
    

    【讨论】:

    • 我不能 100% 确定这是否可行。使用您的服务器端解决方案,您将发送新位置,覆盖保存在道具中的旧位置。我会尽力让您知道并非常感谢您的帮助!
    • 这是在流星中创建分页事物的解决方案。一个更好的好方法。
    • 是的,此修复仅显示“新”发布的 lcoations。您还需要将新位置加入旧位置,我现在在我的内容组件状态下使用 componentWillReceiveProps(nextProps) 完成了这项工作
    猜你喜欢
    • 1970-01-01
    • 2022-12-05
    • 2018-01-02
    • 1970-01-01
    • 2019-04-01
    • 1970-01-01
    • 2013-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多