首页 文章

ReactiveVar不会重新呈现React组件

提问于
浏览
0

我对流星中的React很新 .

TL; DR:在我的数据容器中,更改我的ReactiveVar的值不会重新呈现我的视图 .

我有这个代码:

import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import { Meteor } from 'meteor/meteor';
import { createContainer } from 'meteor/react-meteor-data';

// Mail composer - interface for generating enews
class MailComposer extends Component {
  constructor(props) {
    super(props);
  }

  handleSubmit( event ) {
    event.preventDefault();

    const text = this.refs.mailText.value.trim(),
          title = this.refs.mailTitle.value.trim(),
          rcpts = this.refs.mailRecpts.value.trim();

    console.log(text, title, rcpts);

    if ( text && title && rcpts ) {
      // ...
      this.props.hasTestedIt.set( true );
    } else {
      // ...
    }
  }

  componentDidMount () {
    console.log(this);
    $( this.refs.textArea ).autosize();
  }

  getBtnText () {
    return ( this.props.hasTestedIt.get() ? "Send it" : "Test it" );
  }

  render() {
    let self = this;
    Tracker.autorun(function(){
      console.log(self.props.hasTestedIt.get());
    });

    return (
      <div className="panel panel-default panel-primary">
        <div className="panel-heading">
          <h3 className="panel-title">Mail composer</h3>
        </div>
        <div className="panel-body">
          <form className="form-group" onSubmit={this.handleSubmit.bind(this)}>
            <div className="input-group">
              <span className="input-group-addon" id="basic-addon1">Title</span>
              <input type="text" className="form-control" ref="mailTitle" />
            </div>
            
<label htmlFor="js-recipients">Recipients:</label> <select className="form-control" width="width: initial;" id="js-recipients" ref="mailRecpts"> <option>Admins</option> <option>All</option> </select>
<label htmlFor="comment">Text:</label> <textarea className="form-control" rows="5" ref="mailText"></textarea>
<button className="btn btn-primary" type="submit"> {this.getBtnText()} </button> </form> </div> </div> ); } } MailComposer.propTypes = { hasTestedIt: PropTypes.object.isRequired }; export default createContainer( () => { return { hasTestedIt: new ReactiveVar( false ) }; }, MailComposer);`

但是当我在提交处理程序中设置 ReactiveVar prop时,按钮中 getBtnText 方法返回的文本不会更改 . 我试图将三元组直接放在HTML中,但我得到了相同的结果 . var被正确设置为true,因为autorun正确地记录了更改 .

在另一个已复制此组件的组件中,我正确地重新渲染组件,但在 find 上使用 .fetch()renderTasks 方法映射返回的数组,该方法呈现新组件的列表 .

我错过了什么?我怎么能解决它?

非常感谢 !

1 回答

  • 2

    组件不会更新,因为传递的 hasTestedIt prop本身未更改 . 这是它改变的 Value .

    请注意您实际感兴趣的 Value .

    // Declare the reactive source somewhere appropriately.
    const hasTestedIt = new ReactiveVar( false );
    
    // Watch its value instead.
    export default createContainer( () => {
      return {
        hasTestedIt: hasTestedIt.get()
      };
    }, MailComposer);`
    

    请注意,它现在是传递给 MailComposer 的值,而不是 ReactiveVar ,可以引用它来更新值 . 在这种情况下我们如何更新它?

    一个最简单的方法是通过 hasTestedIt 以及之前,虽然这不是我个人的建议 .

    // Watch its value instead.
    export default createContainer( () => {
      return {
        // Reactive source that triggers re-rendering.
        valueOfHasTestedIt: hasTestedIt.get(),
        // Provided for the contained component to reference to set new values.
        // Leaving this alone doesn't trigger re-rendering!
        hasTested
      };
    }, MailComposer);
    

    这不是优雅的IMO . 另一个是将回调函数传递给 MailComposer ,可以用来更新值 .

    const updateHasTestedIt = ( value ) => hasTestedIt.set( value );
    
    // Watch its value instead.
    export default createContainer( () => {
      return {
        hasTestedIt: hasTestedIt.get(),
        updateHasTestedIt,
      };
    }, MailComposer);
    
    class MailComposer extends Component {
      ...
      handleSubmit( event ) {
        ...
        this.props.updateHasTestedIt( true );
        ...
      }
      ...
    };
    

    这次更好 .

    可以开发更多,但它实际上取决于您对您的应用程序的偏好 . 您和只有您才能做出设计决定 .

相关问题