【问题标题】:How do you isolate changes in React Props/State你如何隔离 React Props/State 的变化
【发布时间】:2016-09-19 21:37:40
【问题描述】:

在 Meteor/React 的上下文中,我有一个订阅 Mongo 数据库的表组件,这个订阅有一个可以通过 props 更新的限制参数。我不知道为什么,但似乎 componentDidMount Lifecycle 函数几乎一直在触发,导致不愉快的闪烁。

代码很长,但我附上了我认为有问题的部分 - 更一般地说,您如何隔离状态/道具的哪些变化导致重新渲染?我已尝试监控 Chrome 工具,但没有发现任何变化。

任何反馈或帮助表示赞赏!

import React from 'react';
import booksSingleLine from '../booksTable/booksSingleLine';
import TrackerReact from 'meteor/ultimatejs:tracker-react';


export default class booksListingTable extends TrackerReact(React.Component) {

constructor(props) {
super(props);
console.log("Constructor props are" + this.props.LimitProp);
}

componentWillMount() {
console.log("Mounting booksListingTable");
console.log("Will mount props are" + this.props.LimitProp);
this.state =   {
}
}

componentDidMount(props){
// console.log("Did mount and props are" +props.LimitProp);
var limit = this.props.LimitProp
limit = parseInt(limit) || 5;
this.state =   {
subscription: {
booksData: Meteor.subscribe("allbooks",{sort: {_id:-1}, limit: limit})
}
}
}

componentWillReceiveProps(props) {
  console.log("component will get new props " + props.LimitProp);
// Note that for this lifecycle function we have to reference the props not this.props
  // console.log("component will get weird props " + this.props.LimitProp);
  var limit = props.LimitProp
  limit = parseInt(limit) || 5;
  this.state =   {
  subscription: {
  booksData: Meteor.subscribe("allbooks", {limit: limit})
  }
  }
}

componentWillUnmount() {

}

booksDataLoad(){
var filteredCity = this.props.FilterProp;
console.log("filter is " + filteredCity);
if (filteredCity) {
console.log("just passing a few things")
return (
  remotebookss.find({location: filteredCity}).fetch()
)
}
else {
console.log("passing everything to table");
return(
remotebookss.find().fetch()
)}}

render() {
return(
  <div>
    <table className="ui celled table">
    <thead>
      <tr>
      <th onClick ={this.props.HeaderOnClick}>Name</th>
      <th>Date</th>
      <th>Summary</th>
      <th>Site address</th>
      <th>Price is</th>
    </tr></thead>
<tbody>
{this.booksDataLoad().map( (booksData)=> {
return <booksSingleLine key={booksData._id} booksData={booksData} />
})}
    </tbody>
    <tfoot>
      <tr><th colspan="3">
        <div class="ui right floated pagination menu">
          <a class="icon item">
            <i class="left chevron icon"></i>
          </a>
          <a class="item" onClick= {this.props.methodLoadMore}>Load More</a>
          <a class="icon item">
            <i class="right chevron icon"></i>
          </a>
        </div>
      </th>
    </tr></tfoot>
  </table>
</div>
)
}
}

【问题讨论】:

  • 我对流星不太熟悉,但我有一种预感——Meteor.subscribe()背后的逻辑是什么?后台会发生什么?
  • 订阅将限制作为选项传递给此发布。 Meteor.publish("allbooks", function (options){ return remoteBooks.find({}, options); });

标签: mongodb meteor reactjs


【解决方案1】:

我强烈建议您阅读以下博客文章 -- https://www.discovermeteor.com/blog/data-loading-react/

我看到的东西:

  1. 你正在到处重置状态
  2. 您没有将订阅作为一个明确的对象进行管理 - 您的代码会泄露它们 (FYI)。

这是一个使用道具和默认道具来设置限制的版本,它仅在启动时检查并更改以更改订阅。

import React from 'react';
import booksSingleLine from '../booksTable/booksSingleLine';
import TrackerReact from 'meteor/ultimatejs:tracker-react';


export default class booksListingTable extends TrackerReact(React.Component) {
    static propTypes = {
        LimitProp: React.PropTypes.number,
    }

    static defaultProps = {
        LimitProp: 5,
    }

    constructor() {
        super();
        console.log("Constructor props are" + this.props.LimitProp);

        const subscription = Meteor.subscribe("allbooks",{sort: {_id:-1}, limit: this.props.LimitProp})
        this.state = {
            booksData: subscription,
        }
    }

    componentWillReceiveProps(nextProps) {
        console.log("component will get new props " + nextProps.LimitProp);

        // Start new subscription - if it's changed
        if (this.props.LimitProp != nextProps.limitProp) {
            // Stop old subscription
            this.state.booksData.stop()
            // Setup new subscription
            const subscription = Meteor.subscribe("allbooks",{sort: {_id:-1}, limit: nextProps.LimitProp})
            this.setState({ booksData: subscription })
        }
    }

    componentWillUnmount() {
        // Stop old subscription
        this.state.booksData.stop()
    }

    booksDataLoad(){
        var filteredCity = this.props.FilterProp;
        console.log("filter is " + filteredCity);
        if (filteredCity) {
            console.log("just passing a few things")
            return (
              remotebookss.find({location: filteredCity}).fetch()
            )
        }
        else {
            console.log("passing everything to table");
            return(
                remotebookss.find().fetch()
            )
        }
    }

    render() {
        return(
              <div>
                <table className="ui celled table">
                <thead>
                  <tr>
                  <th onClick ={this.props.HeaderOnClick}>Name</th>
                  <th>Date</th>
                  <th>Summary</th>
                  <th>Site address</th>
                  <th>Price is</th>
                </tr></thead>
            <tbody>
            {this.booksDataLoad().map( (booksData)=> {
                    return <booksSingleLine key={booksData._id} booksData={booksData} /> 
                })
            }
                </tbody>
                <tfoot>
                  <tr><th colspan="3">
                    <div class="ui right floated pagination menu">
                      <a class="icon item">
                        <i class="left chevron icon"></i>
                      </a>
                      <a class="item" onClick= {this.props.methodLoadMore}>Load More</a>
                      <a class="icon item">
                        <i class="right chevron icon"></i>
                      </a>
                    </div>
                  </th>
                </tr></tfoot>
              </table>
            </div>
        )
    }
}

【讨论】:

  • 感谢新版本和链接,看起来很有用。肯定会消化这个。谢谢!
猜你喜欢
  • 2023-01-09
  • 2019-02-02
  • 2020-05-25
  • 2019-06-05
  • 2018-12-04
  • 2018-05-04
  • 1970-01-01
  • 2018-09-25
  • 1970-01-01
相关资源
最近更新 更多