reflux / refluxjs

A simple library for uni-directional dataflow application architecture with React extensions inspired by Flux
BSD 3-Clause "New" or "Revised" License
5.36k stars 330 forks source link

next evolutionary phase of reflux (cartiv) #468

Closed yonatanmn closed 8 years ago

yonatanmn commented 8 years ago

Hey echosystem, as we all can see, Reflux is dying (not so) slowly, and It's quite sad - first because I really like this library, and secondly because the flux alternatives are missing all the cool features of this lib.

Currently - there are no improvements/tools that this community created lately, and we barely maintain what we already have.

There are two reasons for that - @spoike, the creator of Reflux is no longer actively working on that, and apart from that - Reflux is not fully reactive, and misses some cool features that has been standardized pursuant to Redux.

I would like to suggest here a solution - A totally new library, called Cartiv, that at its core is just Reflux (dependent on reflux-core), but with new terminology (React's terms - e.g setState in the store), reactivity and simplicity.

I really hope that this community will shift to Cartiv, and start a new hype, based on Reflux's great ideas and lack of boilerplate, and new tools and improvements will start to emerge from here.

Do you think it's possible to redeem the flux crown?

devinivy commented 8 years ago

Hey @yonatanmn– happy to have this conversation, but can we move it over to reflux/discuss and link to the new issue from here?

yonatanmn commented 8 years ago

Ok, But please don't close this as many people don't follow reflux/discuss

devinivy commented 8 years ago

I'll leave it open for the week. Anyone following this repo will be notified about this issue and will be linked to discuss if they visit it. Others not following this repo will be directed to discuss for this type of discussion from the readme.

BryanGrezeszak commented 8 years ago

Well, you could just add a Reflux.Component class to reflux that extends React.Component for ES6 type usage. That's why it's dying in my opinion...it doesn't integrate as well into ES6 React in its current form.

I have one that I've been using where you just set this.store (for 1 reflux store) or this.stores (an Array of reflux stores) in the constructor (kinda like you set this.state in the constructor in ES6 style React) and the stores automatically update their own state into the React state on actions. I built it because a client wanted reflux instead of redux (which I had been using) but with this implementation I think reflux becomes more powerful than redux.

Is that something reflux people would be interested in?

jamesmarrs commented 8 years ago

@BryanGrezeszak Sounds cool and I know I would be interested, have you though about making a PR or forking it to let others maybe take a look and give feedback? @devinivy I havent read through all the issues but is anything currently being worked on for making this library ES6 compatible? Might be a good opportunity to get some collaboration on this.

BryanGrezeszak commented 8 years ago

@jamesmarrs - It's pretty light...it's probably more appropriate just to make a working jsfiddle to get a first idea at what people think: https://jsfiddle.net/nq44or92/ and a pastie that's a little easier to read: http://pastie.org/10821394

There's 4 main parts to that, code, most of it is just normal action/store/component setup:

1) an IIFE with the code that attaches the Reflux.Component

2) makes some actions (increment and decrement), nothing special, completely normal actions

3) makes the store, again nothing different except that you keep your state on this.state within the store (something that's idiomatic to concepts in ES6 React anyway)

4) The react class itself. Literally the only thing needed to hook it up to your store is setting this.store in the constructor. That's the important part, so I'll post it here:

class Counter extends Reflux.Component // <- Reflux.Component instead of React.Component
{
    constructor(props) {
        super(props);
        this.state = {foo:'bar'}; // <- stays usable, so normal state usage can still happen
        this.store = counterStore; // <- the only thing needed to tie the store into this component
    }

    render() {
        // `count` and `last` are both from the store, but they reflect on the component state
        return <p>Count {this.state.count}, Last Action: {this.state.last}, Foo: {this.state.foo}</p>;
    }
}

The properties of the store's state just setState themselves into react class' state each time the store triggers a change. Easy as can be. From within the React class you can just treat reading the store as if it's part of the React class state. If you don't want your React state flooded with all the properties in the store then you can just namespace the values in the store such as this.state.counterdata.counter instead of this.state.counter. And multiple stores can update their data into the component via setting this.stores = [store1, store2, etc]; in the constructor. And of course many components can be tied to the same store(s) and update from them.

Just having the store automatically reflected in the state might not be everyone's cup of tea (it lends itself to having a larger number of smaller stores so that each component isn't updating any time anything at all in the app changes...to me more small stores just seems like good practice anyway...but some might disagree). I'm not super well-versed in Reflux culture so I'm not sure if that would be an anti-pattern to you guys...but I find it easy as hang to use. It doesn't get much more simple to implement, and it's completely idiomatic with the type of syntax React is moving toward.

yonatanmn commented 8 years ago

@BryanGrezeszak cool gist. Actually it's quite close to my project. maybe we can join forces!

devinivy commented 8 years ago

Making refluxjs work with ES6 classes is crucial. See #420.

BryanGrezeszak commented 8 years ago

Well...it seems to me that it doesn't get much better for supporting React ES6 than just setting this.store in the constructor. That's about as idiomatic with React ES6 and as easy to use as I can think of.

I've got some lesser well-tested (though seems to work well enough) stuff that I've used to make the stores more ES6 as well. I'm not sure how robust it is, as the stores have proven ridiculously unreliable to try to extend, so I had to go more of a wrapper route: https://jsfiddle.net/g1tetwyz/2/

That example has 1 Reflux.Component class (same concept as above) tied to 2 Reflux.Store classes that are each updating a separate part of the component's state, and are defined like this:

class CounterStore extends Reflux.Store
{
    constructor() {
        super();
        this.listenables = actions;
        this.state = {count:0};
    }

    onIncrement() {
        this.setState({count:this.state.count+1});
    }

    onDecrement() {
        this.setState({count:this.state.count-1});
    }
}

class LastStore extends Reflux.Store
{
    constructor() {
        super();
        this.listenables = actions;
        this.state = {last:'Initialized'};
    }

    onIncrement() {
        this.setState({last:'++'});
    }

    onDecrement() {
        this.setState({last:'--'});
    }
}

Again, that's about as idiomatic React ES6-ish as I can think to make defining stores.


@yonatanmn - I don't think I have time to make a full project out of it! But I can share what I've done for Reflux. That's a neat project though.

BryanGrezeszak commented 8 years ago

I did a fork/PR (with just the Reflux.Component part, not the other stuff I showed in the last comment). Check it out if you'd like.

jamesmarrs commented 8 years ago

@BryanGrezeszak Thanks for sharing some of the work you have done, much appreciated. Going to take a look at this soon

devinivy commented 8 years ago

I also look forward to peeking your PR 👍 – thanks!