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

Possible to use without mixins? #48

Open
elliotlings opened this issue Jun 28, 2015 · 10 comments
Open

Possible to use without mixins? #48

elliotlings opened this issue Jun 28, 2015 · 10 comments

Comments

@elliotlings
Copy link

I'm fairly new to React. Just wondered what the use of mixins provide and whether there's a way around them so I can use ES6 classes?

@tomatau
Copy link
Contributor

tomatau commented Jun 29, 2015

Here's a quick store listener HOC you can use instead of McFly store mixin.

import React from 'react/addons';

const StoreListener = (stores, getStateFromStores, Component) =>
  React.createClass({

    getInitialState(){
      return getStateFromStores(this.props)
    },

    componentDidMount() {
      stores.forEach(store=>
        store.addChangeListener(this.handleStoreChanged)
      )
    },

    componentWillUnmount(){
      stores.forEach(store=>
        store.removeChangeListener(this.handleStoreChanged)
      )
    },

    render() {
      return <Component {...this.props} {...this.state} />;
    },

    handleStoreChanged(){
      this.isMounted() && this.setState(getStateFromStores(this.props))
    }

  })

export default StoreListener;

Use like so:

const Thing = StoreListener(

  [ UserStore, AnotherStore ],

  ()=>({
    isLoggedIn: UserStore.isLoggedIn(),
    thingIsEmpty: AnotherStore.isEmpty()
  }),

  class Thing extends React.Component {

    render(){
      return (
        <div id="wrapper">
          <Loader />
          {(this.props.isLoggedIn && !this.props.thingIsEmpty) ? <SecretStuff/> : null}
        </div>
      )
    }

  }
)
export default Thing;

There's further improvements to be made to this HOC such as performance improvements around props and copying static component properties etc...

@hekar
Copy link

hekar commented Jul 31, 2015

Anything planned for supporting ES6 classes in McFly?

@samhunta
Copy link

This is more of a React issue right? React now supports ES6

@tomatau
Copy link
Contributor

tomatau commented Aug 11, 2015

I've been using this recently

import React from 'react/addons';
import _ from 'lodash';

const StoreListener = _.curry(
  (stores, getStateFromStores, statics, Component) =>
    React.createClass({

      displayName: `${Component.name}StoreListener`,

      statics,

      propTypes: Component.propTypes,

      getDefaultProps: ()=>Component.defaultProps,

      getInitialState(){
        return getStateFromStores(this.props)
      },

      componentDidMount() {
        stores.forEach(store=>
          store.addChangeListener(this.handleStoreChanged)
        )
      },

      componentWillUnmount(){
        stores.forEach(store=>
          store.removeChangeListener(this.handleStoreChanged)
        )
      },

      render() {
        return <Component {...this.props} {...this.state} />;
      },

      handleStoreChanged(){
        this.isMounted() && this.setState(getStateFromStores(this.props))
      }

    })
)
export default StoreListener;

This works as both a HOC or a decorator because of the curry... you just need to make sure all 4 args are passed through..

Use it as a class decorator like so:

@StoreListener(
  [ ItemsStore ],
  ()=>({
    items: ItemsStore.get()
  }),
  {
    willTransitionTo(){
      // static method here, as can't copy static methods from class definition so defining them separately here
    }
  }
)
class ItemsCtrl extends React.Component {

  render() {
    const { items } = this.props;
    return (
      // stuff
    );
  }

}

@kenwheeler
Copy link
Owner

@tomatau that's awesome

@elliotlings
Copy link
Author

Thanks for the help, peeps.

@tomatau
Copy link
Contributor

tomatau commented Aug 27, 2015

No probs, I'm tempted to open source my ES6/7 style version of McFly that I use for in-house projects.. new repository or a PR for v2?

It might be a little redundant now with the progress that other "Flux" frameworks and Relay are making though

@jcperez-ch
Copy link
Contributor

@tomatau @kenwheeler that is a great idea, I know this project has been a bit abandoned but I believe is fantastic. McFly has a lot of future and we can start implementing ideas,patterns and practices from redux, so it can compete with it using the EventEmmitter approach.

I'll fork as well and try to constantly PR more features like @tomatau decorator 👍

Don't give up guys!

@tomatau
Copy link
Contributor

tomatau commented May 27, 2016

Interesting idea @jcperez-ch -- what do you see as benefits for EventEmmitter approach over a functional synchronous approach used in redux?

@jcperez-ch
Copy link
Contributor

jcperez-ch commented May 27, 2016

I need to be honest here @tomatau I don't see benefits over the pure functional synchronous way redux spreads the state over components. That would be the single principle of redux that could be cornered by mcFly, but we can have asynchronous events that can change a single state for the application and we can synchronize (via reducers) the state changes as well.

You can see my branch here: https://github.com/jcperez-ch/mcfly/tree/reduxify_mcfly

I created a guide in another place in another world on how to use reducers and single state in mcFly, so I will add it as example and in the readme.md in my next commit.

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

6 participants