背景:我目前的 Meteor-React 项目是一个教学应用程序,教师可以远程观察学习者在做什么。学习者可以使用许多不同的视图,因此我需要将数据共享方面与视图本身分开。相同的视图将显示在教师的设备上,显示由学生的动作控制。
问题: * 我使用的技术是声音吗?* 当组件的输入没有改变时,如何防止组件被重新渲染?
详细信息:我创建了一个简单的原型(见下文)。这使用 Source 实例(在应用程序本身中将通过 MongoDB 集合更新)为视图组件提供反应性数据。在我的原型中,我只是生成随机数据。
我有两个惊喜。
一:我发现如果我.get()
在源中调用 ReactiveVar,这足以触发 Tracker 对象读取新值,即使我返回一个完全非反应变量的值。正如所料,如果 ReactiveVar 的值没有改变,那么 Tracker 会忽略对非反应变量的任何改变。
二:Tracker获取的值转发给组件props`导致即使值不变也会s
重新渲染。
代码:
import React, { Component } from 'react'
import { ReactiveVar } from 'meteor/reactive-var'
import { withTracker } from 'meteor/react-meteor-data'
/// SOURCE ——————————————————————————————————————————————————————————
class Source {
constructor() {
this.updateData = this.updateData.bind(this)
this.updateData()
}
updateData() {
const reactive = Math.floor(Math.random() * 1.25) // 4 times as many 0s as 1s
data.set(reactive)
console.log("reactive:", reactive)
this.usable = ["a", "b", "c"][Math.floor(Math.random() * 3)]
console.log("usable: ", this.usable)
setTimeout(this.updateData, 1000)
}
get() {
data.get() // We MUST get a reactive value to trigger Tracker...
return this.usable // ... but we CAN return a non-reactive value
}
}
let data = new ReactiveVar(0)
const source = new Source()
/// COMPONENT ———————————————————————————————————————————————————————
class Test extends Component{
render() {
console.log("rendered:", this.props.data)
return (
<div>
{this.props.data}
</div>
)
}
}
export default withTracker(() => {
const data = source.get()
console.log("UPDATE: ", data)
console.log("")
const props = {
data
}
return props
})(Test)
示例控制台输出,带有注释:
reactive: 1
usable: b
UPDATE: b
rendered: b <<< initial value rendered
reactive: 1 <<< no change to reactive value...
usable: a <<< ...so usable value is ignored
reactive: 0 <<< reactive value changes...
usable: c <<< ... so an update is sent to the component
UPDATE: c
rendered: c <<< c rendered
reactive: 0 <<< no change to the reactive value...
usable: c
reactive: 0
usable: b
reactive: 0
usable: c
reactive: 0
usable: b
reactive: 1 <<< but when reactive value changes
usable: c <<< the usable value does not
UPDATE: c
rendered: c <<< c re-rendered, although unchanged
回顾一下:我的计划是每次从学生那里收到新数据时,在我的 Source 实例中增加一个 ReactiveVar。但是,如果学生只是移动光标,那么我只希望显示学生光标的组件重新渲染,而不是整个视图。
对于如何优雅地实现这一目标,我将不胜感激。