Контекст: Мой текущий проект Meteor-React представляет собой обучающее приложение, в котором учитель может удаленно наблюдать за тем, что делает ученик. Есть много разных представлений, которые ученик может использовать, поэтому мне нужно отделить аспект обмена данными от самих представлений. Те же самые виды будут отображаться на устройстве учителя с дисплеем, контролируемым действиями ученика.
Вопросы: * Используется ли техника, в которой я использую звук? * Как предотвратить повторную визуализацию компонента, когда его входные данные не изменились?
Подробности: Я создал прототип «голыми руками» (см. Ниже). При этом используется экземпляр Source (который в самом приложении будет обновляться через коллекцию MongoDB) для предоставления реактивных данных для компонента представления. В моем прототипе я просто генерирую случайные данные.
У меня было два сюрприза.
Первый: я обнаружил, что если я вызываю .get()
на ReactiveVar в источнике, этого достаточно для вызвать объект Tracker для чтения новых значений , даже если я верну значение полностью нереактивной переменной . Как и следовало ожидать, если значение ReactiveVar не изменяется, то Tracker игнорирует любые изменения нереактивной переменной.
Two: Полученное Tracker значение пересылается компоненту s
props` вызывает повторную визуализацию , даже если значение не изменилось .
Код:
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
Подводя итог: Мой план состоит в том, чтобы увеличивать ReactiveVar в моем экземпляре Source каждый раз, когда от студента поступает новая информация. Тем не менее, если студент просто перемещает курсор, то я хочу, чтобы только компонент, который отображает курсор студента, перерисовывал, а не весь вид. элегантно.