Javascript ReactiveVar未重新呈现React组件

Javascript ReactiveVar未重新呈现React组件,javascript,meteor,reactjs,Javascript,Meteor,Reactjs,我对《流星》很陌生 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'; /

我对《流星》很陌生

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>
            <br/>
            <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>
            <br/>
            <label htmlFor="comment">Text:</label>
            <textarea className="form-control" rows="5" ref="mailText"></textarea>
            <br/>
            <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);`
import React,{Component,PropTypes}来自'React';
从“react dom”导入react dom;
从“流星/流星”导入{Meteor};
从“meteor/react meteor数据”导入{createContainer};
//邮件生成器-用于生成enews的接口
类MailComposer扩展组件{
建造师(道具){
超级(道具);
}
handleSubmit(事件){
event.preventDefault();
const text=this.refs.mailText.value.trim(),
title=this.refs.mailttitle.value.trim(),
rcpts=this.refs.mailRecpts.value.trim();
console.log(文本、标题、RCPT);
if(文本、标题和rcpts){
// ...
this.props.hastedit.set(true);
}否则{
// ...
}
}
组件安装(){
console.log(this);
$(this.refs.textArea).autosize();
}
getBtnText(){
return(this.props.hastedit.get()?“发送它”:“测试它”);
}
render(){
让自我=这个;
Tracker.autorun(函数(){
log(self.props.hastedit.get());
});
返回(
邮件生成器
标题

收件人: 管理员 全部的
正文:
{this.getBtnText()} ); } } MailComposer.propTypes={ hastedit:PropTypes.object.isRequired }; 导出默认createContainer(()=>{ 返回{ hastedit:new ReactiveVar(false) }; },MailComposer)`
但是,当我在提交处理程序中设置我的
ReactiveVar
prop时,按钮中的
getBtnText
方法返回的文本不会改变。我曾尝试将三元数直接放入HTML中,但得到了相同的结果。 var被正确设置为true,因为自动运行程序正确地记录了更改

在另一个复制了这个组件的组件中,我确实正确地重新命名了该组件,但是在
find
上使用
.fetch()
将返回的数组映射到一个
renderTasks
方法中,该方法渲染了新组件的列表

请问我错过了什么?我怎样才能修好它呢


非常感谢

组件不更新,因为传递的
hastedit
属性本身没有更改。改变的是它所持有的价值

注意你真正感兴趣的价值

// 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
。在这种情况下,我们如何更新它

一个最简单的方法是像以前一样通过
hastedit
,尽管这不是我个人的建议

// 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);
另一个是将回调函数传递给
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 );
    ...
  }
  ...
};
这次比较好


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

组件不会更新,因为传递的
hastedit
属性本身不会更改。改变的是它所持有的价值

注意你真正感兴趣的价值

// 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
。在这种情况下,我们如何更新它

一个最简单的方法是像以前一样通过
hastedit
,尽管这不是我个人的建议

// 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);
另一个是将回调函数传递给
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 );
    ...
  }
  ...
};
这次比较好


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

当您像以前一样容易传递
hastedit
时,您的意思是直接传递容器中的值吗?如果是这样的话,更改该值仍然可以启动重新渲染器,尽管它不是来自reactiveVar?非常感谢您的帮助。@David Panart,是的。如果在浅层比较中未更改
createContainer
的返回值,则不会触发重新渲染,尽管
hastedit
是一个反应源。当您与以前一样容易传递
hastedit
时,是否要直接传递容器中的值?如果是这样的话,更改该值仍然可以启动重新渲染器,尽管它不是来自reactiveVar?非常感谢您的帮助。@David Panart,是的。如果在浅层比较中未更改
createContainer
的返回值,则不会触发重新渲染,尽管
hastedit
是被动源。