Giter Site home page Giter Site logo

fluxxor's Introduction

Fluxxor

Fluxxor is a set of tools to aid in developing React applications with the Flux architecture.

Travis CI

NPM

Installation

Fluxxor is available on npm and works with module bundlers like Browserify and Webpack.

npm install [--save] fluxxor

Standalone browser builds can be downloaded from the GitHub releases page or installed via Bower:

bower install fluxxor

More detailed installation instructions can be found on the Fluxxor website.

Third Party Releases

The following releases are maintained by third parties, and support inquiries should be directed to their maintainers.

WebJar

For JVM languages, there are WebJar packages available on Maven Central and jsDelivr as the following:

SBT/Play Framework 2:

"org.webjars" % "fluxxor" % fluxxorVersion

Maven:

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>fluxxor</artifactId>
    <version>${fluxxor.version}</version>
</dependency>

For detailed instructions, refer to the WebJars documentation. For update requests, open a pull request on the Fluxxor WebJar repository on Github.

Browser Compatibility

Fluxxor is compatible with any ES5-compliant browser (IE 9+, FF 4+, Safari 5.1.4+, Chrome 19+, Opera 12.10+). You can use es5-shim for other browsers.

Documentation

See the Fluxxor website for in-depth documentation, installation instructions, examples, and a getting started guide.

Support and Chat

Get help with and chat about Fluxxor on Gitter.

Gitter chat

License

Fluxxor is licensed under the MIT license.

The MIT License (MIT)

Copyright (c) 2014 Michelle Tilley

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

fluxxor's People

Contributors

andy-williams avatar astraw avatar benhc123 avatar binarymuse avatar blrhc avatar davidbgk avatar evax avatar jtangelder avatar lucasjans avatar mhussa avatar randallsquared avatar sammyk avatar skevy avatar strml avatar tarrsalah avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fluxxor's Issues

Explore mixins, etc. for transitive state

E.g. a form submits via an action, then the action errors. We want to display the error to the user, but when the form goes away we want to stop storing the error (or, at minimum, ensure it doesn't show the next time we display the form).

We can clear the error with an action in componentWillUnmount, which requires more boilerplate than we'd like. Maybe there's a way to generalize this transitive state problem to make dealing with these kinds of things easier.

See also https://gist.github.com/thomasboyt/5a2fda0db3af7d93c8b6 by @thomasboyt

Bower support

I think that would be awesome to declare a bower.json file with only the browser ready implementation, excluding examples and npm only files, to allow easy installation for browser only use.

Thoughts on explicitly enforcing the Flux pattern

I just wanted to throw some thoughts out there and see what you guys think. Some of these were brought up in #10.

Removing this.context dependency

The FluxChildMixin relies on receiving the flux object via this.context which React passes to the components automatically. There are a few good reasons this should be avoided.

  1. Since contexts are intentionally not documented and subject to change, there are a lot of context-related BC's going at the main repo.
  2. Context is only passed to children that are rendered within the render() method. Here's an example of how context gets lost. And cloneWithProps() doesn't copy context or owner. This is problematic since lots of React-based repos use it. For example when using ModalTrigger in react-bootstrap, the context doesn't get passed to the Modal components. To get around this you can explicitly pass in the flux object, but my point is that should be done all the time (see next section). :)
  3. One nice aspect of the "React way" is the explicit idiomatic propagation of dependancies down the component tree. Having a dependency magically handled for you in the background seems to be an anti-pattern to both React's philosophy and the Flux pattern.

Explicitly passing stores and actions to components

Since the root controller-view is the only component that needs to watch for changes of the state of the store, the store should be explicitly passed to it exclusively. The actions would be passed as a separate prop (or props) and could be further passed down the component tree exclusively.

var ChildComponent = React.createClass({
    propTypes: {
        myActions: React.PropTypes.object.isRequired,
        immutableStoreState: React.PropTypes.object.isRequired
    },
    doSomething: function() {
        if(this.props.immutableStoreState.readOnlyThing) {
            return this.props.myActions['FooActions'].someAction();
        }
        return this.props.myActions['FooActions'].someOtherThing();
    },
    render: function() {
        return (
            <div>
                <h2>Child Component</h2>
                <p onClick={this.doSomething}>Click me</p>
            </div>
            );
    }
});

var StoreWatchMixin = Fluxxor.StoreWatchMixin;

var RootControllerView = React.createClass({
    mixins: [StoreWatchMixin("FooStore")],
    propTypes: {
        myStores: React.PropTypes.object.isRequired,
        myActions: React.PropTypes.object.isRequired
    },
    getStateFromFlux: function() {
        return this.props.myStores['FooStore'].getState();
    },
    render: function() {
        return (
            <div>
                <h1>My App</h1>
                <ChildComponent myActions={this.props.myActions} immutableStoreState={this.getStateFromFlux()} />
            </div>
            );
    }
});

var flux = new Fluxxor.Flux(storesObject, actionsObject),
    stores = flux.getStores(),
    actions = flux.getActions();

React.renderComponent(
    <RootControllerView myStores={stores} myActions={actions} />,
    document.getElementById('my-app')
);

The StoreWatchMixin is really nice since it's pretty strictly Flux and you can learn the "Flux way" of handling the store state by examining the mixin source code.

This would eliminate the need to have FluxMixin and FluxChildMixin and thus the this.context dependency. We might still need to pass in the flux object for the StoreWatchMixin.

Fluxxor's Role

I guess the real question is what role does Fluxxor want to take? Is it designed to help enforce a strict Flux architecture? If so, people who want to better understand Flux by using this package would really benefit from the points above.

I'd love to hear your thoughts. :)

Only one action can be dispatched at a time

Hello and thanks for your work here.

I've encountered a limitation of the dispatcher implementation that prevents me from having multiple actions being dispatched at the same time. While I think I do understand the reasons behind this limitation, I'd like to be sure to understand them. Could you enlighten me here please?

Anyway, I changed my code to avoid this but from what I understand from Flux and particularly in the case of various action sources, I will meet them again if I have:

  • view_actions
  • server_actions (xhr)
  • realtime_actions (websocket)

How can I ensure that there will be one and only one action trigger at a given time since I cannot predict when all those actions are sent? I was thinking of making the dispatcher managing a queue but it's not in the official dispatcher implementation (see http://facebook.github.io/flux/docs/dispatcher.html) so I guess I'm missing something.
That's probably something I should ask the React/Flux team though, but you might help me to figure this out.

Changelog?

1.5.0 has some breaking changes (removal of FluxChildMixin, etc.). Could you add a changelog when making breaking changes so we know how to upgrade?

Add .jshintrc

Hi - without the .jshintrc you used to develop this project, a contributing developer's jshint settings can cause the jshint test job to fail. Could you include the one you expect this project to match and commit it to the root?

rollback

after quickly browsing the code (good stuff), I can't seem to find anything related to rollbacks. I.e: the ability to rollback to a previous consistent state for all stores, when 1 or more stores fail. Is this something planned / wanted?

Does "Cannot dispatch an action while another action is being dispatched" ever throw? It seems not.

"Cannot dispatch an action while another action is being dispatched" throws when attempting to dispatch an action when a sync action is being dispatched.

What's the chance of that actually happening? It seems to be zero as far as I can tell: a new action will register at the end of the eventloop/current tick, meaning all sync actions are guarenteed to be finished before the dispatcher has a chance to register the new event and do the above check.

What am I missing?

Add getStateFromFlux to StoreWatchMixin

For a single store component the code could be reduced.

mixins: [ FluxMixin, StoreWatchMixin('FooStore') ],

getStateFromFlux: function() {
    return this.getFlux().store("FooStore").getState();
},

to:

mixins: [ FluxMixin, StoreWatchMixin('FooStore') ],

The getStateFromFlux could be set by default in StoreWatchMixin with the passed 'FooStore'.

If more stores are used, we should think about to respond an object with the store-names and states, or throw an error with the hint to implement an own getStateFromFlux function. (i am not sure which solution will be developer friendlier).

Docs out of date for dispatching actions?

Hi - thanks for creating Fluxxor, it's a useful little library :)

Just curious if, as I suspect, the docs here are out of date: The Actions docs say to dispatch actions like so: flux.dispatcher.dispatch(type, {payload: 'payload'}), while the code implies they should be dispatched like: flux.dispatcher.dispatch({type: 'type', payload: 'payload'}).

If so, I can create a pull request if you'd like.

No symbols in strings

It would be nice if JS symbols weren't included in strings so they could be statically analyzed (i.e. linted, minified, and type checked). If the actions map mapped directly to the function itself (rather than a string containing the name of the function) this would work well.

To-do line-through doesn't work on firefox (29.0.1)

In your to-do example. The object the span uses to put a line through clicked items, the property name isn't in camelcase, it should be:

"textDecoration": (this.props.todo.complete ? "line-through" : "")

Weird thing is, "text-decoration" works in chrome and desktop safari, but not on firefox.

Thanks for your implementation of flux btw. The to-do not working (or looking like it didn't) did put me off at first but the flux concepts were too good to ignore.

Error when using webpack require

Im trying to do "var Fluxxor = require('fluxxor');" in one of my files and I get::

ERROR in .//fluxxor/package.json
Module parse failed: /Users/seanbrant/Projects/octave/node_modules/fluxxor/package.json Line 2: Unexpected token :
You may need an appropriate loader to handle this file type.
| {
| "name": "fluxxor",
| "version": "1.1.1",
| "description": "Flux architecture tools for React",
@ ./
/fluxxor/index.js 15:11-36

Pull actions out of Flux constructor, generate via factory method

Using actions to generate actual action objects allows for very semantic-looking method calls to generate and dispatch actions, and the extra bind used in the Flux constructor decouples action generating functions from the actual shape of an action object.

We want to continue to provide those benefits while also allowing for:

  1. Namespaced actions (e.g. actions.namespace.action(...))
  2. Easier dispatching without using action generating functions at all (I think the extra indirection is a good idea, but it's been requested a few times)

By generating action objects with a factory method from Fluxxor, we can continue to decouple action generating functions and the actions themselves, and allowing actions to be generated anywhere allows considerably more flexibility.

Pseudocode:

// todo_actions.js

var Fluxxor = require("fluxxor");

module.exports = {
  ADD_TODO: "TODO:CREATE",
  TOGGLE_COMPLETE: "TODO:TOGGLE_COMPLETE",

  addTodo: function(text) {
    return Fluxxor.action(this.ADD_TODO, {text: text});
  },

  toggleComplete: function(todo) {
    return Fluxxor.action(this.TOGGLE_COMPLETE, {id: todo.id});
  }
};

// some_store.js

var TodoActions = require("todo_actions");

Fluxxor.createStore({
  initialize: function() {
    this.bindActions(TodoActions.ADD_TODO, this.handleAddTodo);
  }
});

// some_component.js

var TodoActions = require("todo_actions");

React.createClass({
  // ...

  handleClick: function() {
    this.getFlux().dispatch(TodoActions.addTodo(this.state.text));
  }
});

This may also be a good opportunity to clarify names; in particular, "action" is fairly overloaded. Another random but related thought is to rename dispatch to act or something similarly a bit more semantic; e.g. this.getFlux().act(Actions.something(...)).

Typo in FAQ

Page:

http://fluxxor.com/faq.html

Question:

'Q: Why do I see a warning that says "possible EventEmitter memory leak detected"?' (It's the final question as of the writing of this issue)

Typo:

The typo is in the answer, in the final sentence. "... you can call setMaxListeners(n) on your store (use can use a value of 0 for unlimited)."

Should be:

"... you can call setMaxListeners(n) on your store (you can use a value of 0 for unlimited)."

Namespace clash

The Free and Open Source Fluxbox window manager has been around for ages (even has #fluxbox on freenode) - http://fluxbox.org/

It'd be nice to keep our namespaces sane and clear

Thanks!

Bring back fluxbox.io

Hey Brandon,

Fluxbox is really good and #1 on reddit.com/r/javascript and a tweet with 20+ retweets/favorite.

I know that you have been asked to rename it but can you bring back the website in the meantime? A lot of people are asking why it 404 right now.

It would be best to leave it as is for this press cycle and then in a day or two when it cooled off to rename it

Thanks!

Do Action objects serve any real purpose ?

Action objects like the following:

var actions = {
  addUrl: function(url, index) {
    this.dispatch("ADD_URL", {url: url, index: index});
  }
};

seem like a superfluous layer of indirection that provides no real advantage.

Is there any advantage to having the action objects at all rather than just making a singleton dispatcher available to the views. After all, all that the actions seem to do is translate method calls to dispatch calls, passing on their payload. Why couldn't the views make dispatch calls directly ?

Strange code behavior in async application example

32cb5cb#diff-84db15b964bc791938cc5f00b0df2e31R107

this.loadingWords[payload.id].status = "OK";
delete this.loadingWords[payload.id];

32cb5cb#diff-84db15b964bc791938cc5f00b0df2e31R113

this.loadingWords[payload.id].status = "ERROR";
this.loadingWords[payload.id].error = payload.error;
delete this.loadingWords[payload.id];

(Also the same lines in the documentation)

Why update something that is going to be deleted? I see the intention, but the code is obviously wrong.

Store creation is too inflexible

There's no good way to create reusable bits of stores, for example, default methods, action handlers, or initialize methods. See #31 for a good example.

Mixins could certainly do the trick (merge action hashes, call multiple initialize methods, mix in other methods and properties), but I'm not sure if it's the best solution for the problem.

collection store sugar

Some sugar for simple stores. It implements handleAdd, handleRemove, handleEmpty, getState, emptyWhere, setCollectionName.

var TodoStore = Fluxxor.createCollectionStore({
  actions: {
    "ADD_TODO": "handleAdd",
    "TOGGLE_TODO": "handleToggleTodo",
    "CLEAR_TODOS": "handleClear"
  },

  initialize: function() {
    // provide the property name to fluxxor
    this.setCollectionName("todos");
  },

  handleToggleTodo: function(payload) {
    payload.todo.complete = !payload.todo.complete;
    this.emit("change");
  },

  handleClear: function() {
    this.removeWhere(function(todo){
        return todo.complete;
    });
    this.emit("change");
  },
});

Server side

Is it possible to use fluxxor for a server side rendering of react? Any examples?
Also if we use sync call of dispatcher actions, then it is incompatible with nodejs async style.

EventEmitter memory leak warning, once application goes beyond a trivial size

I have a page with a lot of views, stores and actions, and the console is throwing up a warning:

(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit. 

It's not breaking anything, but it's unwanted output. I'm not sure of the right approach to suppressing this, perhaps Fluxxor should set its listener limit to 0 (ie unlimited), or make it simple to configure.

In Routing mixin, what pattern should one use with an AuthStore?

I have a mixin that captures route transitions under react-router, and it needs access to a particular Store instance:

module.exports = {
  statics:
    willTransitionTo: function(transition) {
       // Need to get AuthStore instance here
       // if (!AuthStore.loggedIn) { }
    }
 }

This would hypothetically allow for a { mixins: [AuthenticatedRoute] } on React classes.

What pattern would you guys use that doesn't involve attaching anything to window?

Better alternative to webpack

I was wondering if webpack is the best approach to build this library. I looked at the build file generated and looks really bloated by webpack's declarations. Also I think it is better to express external dependencies rather than bundled it together.

What do you think of we refactor the code and use some structure that enables use with CommonJS and AMD, but keeping the simplicity of the library. The source has only 7 files, with nearly 300 lines, excluding lodash functions. Maybe simply use UMD and expressing an external dependency on lodash code is the best way to go.

What do you think?

Uncaught TypeError: undefined is not a function for addActions

I'm seeing addActions as undefined when creating a Flux object.

Here's my code.

var Fluxxor = require("fluxxor")
 ,  merge   = require("react/lib/merge")
 ,  React   = require("react/addons")
 ,  Router  = require("./routers/router");

var ProductStore = require("./stores/product_store");

var ProductActionCreator = require("./actions/product_action_creator");

// stores
var stores = {
  ProductStore: new ProductStore()
}

// actions
var actions = merge(ProductActionCreator);

var flux = Fluxxor.Flux(stores, actions);

Fluxxor.Flux(stores, actions) is where the error gets thrown.

Questions on the implementation

Hi @BinaryMuse,

I lost you on IRC yesterday, so I'm putting the same questions up here :):

  1. if views are only meant to trigger actions (which you point on the docs), wouldn't it be better
    if only actions would be available in views? This would force the developer to get off the comfort
    zone and realise that it isn't the intended way and it would also make the syntax cleaner.
  2. what's the difference between FluxMixin and FluxChildMixin? Or, in other words, why does FluxMixin tell the child context if a child view is intended to use FluxChildMixin and get flux using this.getFlux()?
  3. have you thought about namespacing actions? I know that they're supposed to have a unique constant that tells them apart (e.g., ADD_URL), however I have a feeling that this approach may eventually lead to less clarity on which actions the view depends on.

Thanks in advance for your time,
Darío

Flubox??

Heading reads Flubox.Flux ... what is??

Web worker support?

Not sure if this is in scope, but it would be very cool (and easy I think) if Fluxxor supported running in a web worker. That way your "business logic" (which likely contains a lot of data) can exist off of the main thread, avoiding GC pauses and long processing times if they exist.

WebJar release

Hi,

There's a recent project called WebJars which is:

WebJars are client-side web libraries (e.g. jQuery & Bootstrap) packaged into JAR (Java Archive) files.

  • Explicitly and easily manage the client-side dependencies in JVM-based web applications
  • Use JVM-based build tools (e.g. Maven, Gradle, SBT, ...) to download your client-side dependencies
  • Know which client-side dependencies you are using
  • Transitive dependencies are automatically resolved and optionally loaded via RequireJS
  • Public CDN, generously provided by jsDelivr

It's very convenient when working on JVM-related web project, especially using build tools like Maven, SBT, etc., so that I prepared a WebJar repo. I'll open a request to publish it on Maven Central if you want. What do you think?

Create example with async data fetching

This has come up several times (IRC, Gitter), so the documentation should be more explicit, ideally with an example. Things to address:

  • Reasoning for this architecture
  • Fetching data in multiple stores or from multiple endpoints
    • Discrete events vs. single event
    • Progressive rendering (Oboe.js?)
  • Error handling (semantic actions for "rolling back" or marking as failed)

Clarify comment in quickstart's Application.getStateFromFlux

In the quickstart Application.getStateFromFlux there's this comment. I'm confused as to what it means. What key is this referring to? What would using one key per store look like?

  getStateFromFlux: function() {
    var flux = this.getFlux();
    // Normally we'd use one key per store, but we only have one store, so
    // we'll use the state of the store as our entire state here.
    return flux.store("TodoStore").getState();
  },

Thanks! Loving fluxxor so far!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.