Meteor + React + Sessions and Efficiency Problem


#1

As in the title, I have an issue with those and I need to find out what is the best way to achieve?

  • App has multiple language support
  • App needs to listen window resize event
  • App has lots of content on single page

Normally I can listen window resize event in every component but I did this instead.

main.coffee

Meteor.startup ()->
	updateWindow = ()->
		w = $(window).width()
		h = $(window).height()

		Session.set "window",
			width: w
			height: h

	updateWindow()

then in

app.coffee (this is the parent route holder)

React = require "react"
{div,span}= React.DOM

createContainer = require("meteor/react-meteor-data").createContainer

View = React.createClass

	shouldComponentUpdate:(nextProps,nextState)->
		return true


	extendedProps:()->
		extensions = 
			app: app

		Object.assign {}, @props , extensions

	render: ()->
		if @props.userSubscriptionReady
			React.cloneElement @props.children, @extendedProps()
		else
			div {}, "Loading"


meteorContainer =  (props)->
	
	# Set Language
	currentLanguage = localStorage.getItem("lang") or app.default.language
	TAPi18n.setLanguage(currentLanguage)

	userSubscription = Meteor.subscribe("currentUser")

	objects =
		userSubscriptionReady: userSubscription.ready()
		currentUser: Meteor.user() or {}
		currentLanguage: TAPi18n.getLanguage()
		allLanguages: TAPi18n.getLanguages()
		window: Session.get("window")

	return objects

module.exports = createContainer meteorContainer , View

after this you probably get the idea how I will using this; this is it

home.coffee (end)

.
.
.
# bind meteor
meteorContainer =  (props)->
	# Contents
	contents = []
	for i in [0...5]
		contents.push generateEmptyContent(i)

	return { 
		contents: contents
	}

module.exports = createContainer meteorContainer , View

So the problem is when I resize the window I got different contents on every scroll event


Lets think, it could be a subscription so meteor container or/and react component would render/get data every time I resize.

I tried to stop the rendering in (normally I pass necessary props to states)

componentWillReceiveProps:(nextProps)-> **here**

and I succeed but I still didn’t stop meteorContainer to run in every resize.


So…

Is meteor can handle these kind of things( somehow are subscriptions will be debounced or ? ) or should I use different approach to pass “window/currentLanguage” values?

If the answer is the second, got any idea?

Thanks in advance :wink:


#2

I don’t really understand this point.

I also do not see how you use the window-size.

But you should clearly avoid using your window-session-variable in the root-component. This will lead to re-rendering of the whole react-tree on every window-change.

Also try to throttle or debounce your window-resizing and use Session.get(“window”) only where you really use it.

also i would not name it “window”, as this might lead to confusion with the browser’s window-object.


#3
  1. I mean when I resize the browser meteorContainer runs every time (I guess it is normal because I changed a session)
  2. I’m using window-size to change the UI elements (some of them depends on this can’t do it with css)

As you mentioned, it is not wise to bind window event to a session right?

If it is, how can I do that in react(global window event bind)?


#4

you can bind the window event to a session, but you should use it only where you really need it.

I would also try to throttle or debounce the resize-handler (see https://css-tricks.com/debouncing-throttling-explained-examples/)

Just out of curiosity: what do you try to change on ui-resize that you can’t do with css?


#5

I’m building a drag’n drop editor and I need to listen window resize on lots of components to update the ui beacuse of that I was trying to do something global like session but it appears sessions are too global :slight_smile:


#6

the “globalbility” of Session is not the problem. A problem arises, if your whole react-tree needs to rerender on every window-resize event. Remember: the resize event triggers multiple times per second on most browsers! So it’s best to throttle it (with lodash / underscore) or try to avoid it (You can use flexbox for more complex layouts). Even in a drag-drop-editor this should be possible.