Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flux / dispatcher usage #70

Closed
emmenko opened this issue Mar 10, 2015 · 16 comments
Closed

Flux / dispatcher usage #70

emmenko opened this issue Mar 10, 2015 · 16 comments

Comments

@emmenko
Copy link

emmenko commented Mar 10, 2015

Hi @acdlite,

first of all thx for making this library, it has really nice concepts and looks really promising.

I've been playing around a little with it and there are couple of things I'm not 100% sure, so I'd like to ask you ;)

  1. Let's say I have lots of stores / actions in my application. How should I use the Flux container? Should I create one for the entire application with all actions / stores declared in it or should I create many of them and instantiate them only where needed (e.g.: one for general application usage, one for a specific page, ...)?
  2. With the standard singleton dispatcher, every action would go through that place, making easy to keep an history and debug. When using multiple instances though, there are "multiple" dispatchers, loosing then the ability of having everything flowing through a central place (although there are other benefits). Is that correct? Could you maybe clarify that and how would you handle that situation?

Thanks :)

@acdlite
Copy link
Owner

acdlite commented Mar 10, 2015

Hi! Thanks for the kind words.

  1. This is really up to you. The traditional Flux approach is to use a single container, and generally that's the way to go, but because Flummox does not use singletons, there could be cases where you need or want a local Flux class. v3.0 will make this easier by allowing you to customize the name of FluxComponent's flux prop to avoid clashes. Make flux key configurable for FluxComponent #60
  2. Yes, and that's why you generally want to use a single Flux instance. I would say only use separate instances if they have completely isolated concerns. You could use actions communicate between Flux instances, but at that point you should probably just combine them.

Hope that helps!

@acdlite
Copy link
Owner

acdlite commented Mar 10, 2015

To clarify, the main purpose of Flux's non-singleton, everything-is-an-instance approach is to enable server-side rendering. It just also happens to have other benefits, like the ability for local Flux. But the recommended approach is still for a single, "global" Flux class.

@emmenko
Copy link
Author

emmenko commented Mar 10, 2015

  1. Yep, saw the roadmap ;)
  2. Ok that makes sense. Just one question though: if I have only 1 instance of Flux, every action / store created in it will be referenced in the container (_stores, _actions). So we might have a big fat object here that we ideally pass through all our React components. Are there any bad consequences about that or something we need to be careful?

@acdlite
Copy link
Owner

acdlite commented Mar 10, 2015

JavaScript passes objects by reference, so the fatness of the object makes no difference. Unless I misunderstood your question, which is possible :)

@emmenko
Copy link
Author

emmenko commented Mar 10, 2015

Yeah, just wondering if it's ok to pass those "complex" objects as props (it's a question more related to React I guess).
Also, would you recommend to pass the flux instance directly to React context or use props? Are there any drawbacks or does it make no difference at all?

@acdlite
Copy link
Owner

acdlite commented Mar 10, 2015

Using props is more explicit but it doesn't scale well. I suggest using FluxComponent:

// entry point
// this adds flux to context
React.render(
  <FluxComponent flux={flux}>
    <App />
  </Flux>
, el)

// elsewhere, use FluxComponent to access flux
<FluxComponent>
  <Something /> // has flux prop
</FluxComponent>

@emmenko
Copy link
Author

emmenko commented Mar 10, 2015

Yes, I meant this as props ;)

The other option I saw somewhere was by using React.withContext.

But yeah, I guess I can just wrap my App component in a FluxComponent and inject flux there.

👍

@acdlite
Copy link
Owner

acdlite commented Mar 10, 2015

React.withContext() is deprecated in 0.13 https://github.com/facebook/react/blob/master/src/core/ReactContext.js#L54

@emmenko
Copy link
Author

emmenko commented Mar 10, 2015

Perfect, thanks for the help 👍

@emmenko emmenko closed this as completed Mar 10, 2015
@emmenko
Copy link
Author

emmenko commented Mar 10, 2015

@acdlite hey sorry to bother you again. I've adjusted my example by wrapping a FluxComponent and got a weird behaviour. Let me show you:

import Dispatcher from './Dispatcher'

let dispatcher = new Dispatcher()

let Application = React.createClass({
  render() {
    return (
      <FluxComponent flux={dispatcher}>
        <div>
          <FluxComponent connectToStores="user">
            <TopNav />
          </FluxComponent>
          <div>
            <div>Left nav</div>
            <div>Main content</div>
          </div>
        </div>
      </FluxComponent>
    )
  }
})

export default Application
---
import Application from './Application'

React.render(<Application />, document.getElementById('app'))

# doesn't work!
# Uncaught Error: fluxMixin: Could not find Flux instance. Ensure that your component has either `this.context.flux` or `this.props.flux`.
let Application = React.createClass({
  render() {
    return (
      <div>
        <FluxComponent connectToStores="user">
          <TopNav />
        </FluxComponent>
        <div>
          <div>Left nav</div>
          <div>Main content</div>
        </div>
      </div>
    )
  }
})

export default Application
---
import Application from './Application'
import Dispatcher from './Dispatcher'

let dispatcher = new Dispatcher()

React.render(<FluxComponent flux={dispatcher}><Application /></FluxComponent>, document.getElementById('app'))

# it works!

Any idea why?

@emmenko emmenko reopened this Mar 10, 2015
@acdlite
Copy link
Owner

acdlite commented Mar 10, 2015

Ah, there is a very subtle difference. In React 0.12 and below, context is owner-based, not parent-based. (A component's owner is the one that renders it, whereas the parent is the one directly above it in the component tree.) So the first example will not work because the inner FluxComponent it does not have an owner who provides flux as context. It's kind of hard to explain, but hopefully that's clear.

In React 0.13, context will be parent-based instead facebook/react#2112

@emmenko
Copy link
Author

emmenko commented Mar 10, 2015

Hmm ok I think I get it.
Long story short, if I use React 0.13 the first example should work...right?

Thanks for the explanation! :)

@acdlite
Copy link
Owner

acdlite commented Mar 10, 2015

No problem! Yes, I believe the first example should work in React 0.13.

@emmenko
Copy link
Author

emmenko commented Mar 10, 2015

👍

@ericf
Copy link

ericf commented Apr 5, 2015

Ah, there is a very subtle difference. In React 0.12 and below, context is owner-based, not parent-based.

This is incorrect. In 0.13, context is still owner-based, and a warning has been added in 0.13 to notify people of the upcoming switch to parent-based context. See facebook/react#3392 (comment)

@acdlite
Copy link
Owner

acdlite commented Apr 5, 2015

Yes you're right.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants