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

FluxComponent #293

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

FluxComponent #293

spoike opened this issue Mar 16, 2015 · 10 comments
Milestone

Comments

@spoike
Copy link
Member

spoike commented Mar 16, 2015

Implement a convenience component for ReactJS that lets you use a component instead of mixins to hook up stores, joins and actions. Much like FluxComponent from Flummox.

Simplest possible is a component that looks like this in jsx code:

var App = React.createClass({
  return (<MainLayout>
    <Reflux.Component connect={
      "my": MyStore,
      "another": AnotherStore
    }>
      { /* All props.children will be connected using Reflux.Component's props.connect object */ }
      <Toast />
      <Whatever />
    </Reflux.Component>
  </MainLayout>);
});
@spoike spoike added this to the 0.2.8 milestone Mar 16, 2015
@maxguzenski
Copy link
Contributor

and what you think something like that:

// it will pass my and another as properties (just remove store from end)
<Component myStore anotherStore>...</Component>

// it will pass my1 and another1 as properties
<Component myStore='my1' anotherStore='another1'>...</Component>

// it will pass my and another as properties and use function data filter
<Component myStore={myFilter1} anotherStore={myFilter2}>...</Component>

// when need to config property name and filter
<Component myStore={{name: 'model1', filter: myFilter}} anotherStore={{name: 'model2', filter: myFilter2}}>...</Component>

// or as array
<Component myStore={['model1', myFilter]} anotherStore={['model2', myFilter2]}>...</Component>

or maybe, property is children name

<Component model1={MyStore} model2={AnotherStore}>...</Component>

<Component model1={{store: MyStore, filter: myFilter}} model2={{store: AnotherStore, filter: myFilter2}}>...</Component>

// or
<Component model1={[MyStore, myFilter]} model2={[AnotherStore, myFilter2]}>...</Component>

@maxguzenski
Copy link
Contributor

A question, what happens when you have something like that:

<NeedMyStore><NeedAnotherStore /></NeedMyStore>

// will you end up with something like that??
<Component myStore>
  <NeedMyStore>
    <Component anotherStore><NeedAnotherStore /></Component>
  </NeedMyStore>
</Component>

@spoike
Copy link
Member Author

spoike commented Mar 17, 2015

@maxguzenski I believe components should do store registration by themselves. So if a nested component needs a store that the parent doesn't need to know about, they should do it instead of the parent.

In other words NeedMyStore will do the following render:

<Reflux.Component connect={"myStore": MyStore}>
  <AnotherStore />
</Reflux.Component>

... and AnotherStore will do the following render:

<Reflux.Component connect={"anotherStore": AnotherStore}>
....

@maxguzenski
Copy link
Contributor

You are right about parent component...

I think this component can be a nice feature of reflux (and for any flux framework). But I just no sure if I agree with Flummox arguments about this component.

1º - Re-render just what needed
But this all what React is about, isn't? Just let re-render. With immutable data time difference between re-render all page and just a small scope will be very small, no?

2º - Make react component truly reusable
I dont know about other projects, but in my case, top root elements (thats one connect with store) not "born" to be reusables (they are a role page, or page specific)

@spoike
Copy link
Member Author

spoike commented Mar 17, 2015

I think this is an optional convenience... like most other things Reflux has.

@juliankrispel
Copy link

@spoike so I started writing an implementation of this as specified by you but got stuck because there doesn't seem to currently be a dom-based testing environment setup for this repo. Yet I can see phantomjs mentioned somwhere in the karma config file.

Can you shed some light on this? Do you have plans to integrate jest or anything that helps test react components? I'd really like to help but think it would really make sense to test with actual react components in this case.

@spoike
Copy link
Member Author

spoike commented Aug 1, 2015

@juliankrispel At the moment only unit tests on reflux functionality is available (w. mocha and karma), but no actual integration tests with dom-based environment.

I recently got the karma tests running on sauce labs and am under way to integrate reflux-core into reflux/refluxjs. Once that's done I should be able to add a dom-based testing environment with jest if time persists. I would like some help on these tests though, so pull requests are greatly appreciated.

@morlay
Copy link

morlay commented Nov 18, 2015

@spoike
After using reflux in some projects,
feel a little painful for testing the Components which are subscribed to stores or call actions inside.

Stores have will keep state, we have to mock lots of things.

So learning from redux, I made reflux-connect to solve the pain point.

import React from 'react';
import refluxConnect from 'reflux-connect';

import storeA from '../stores/storeA';
import storeB from '../stores/storeB';
import commonActions from '../actions/commonActions';

const componentConnect = refluxConnect({
  storeA: storeA,
  storeB: storeB   
})((state) => {
  // connectFilter can did here
  return {
    storeA: state.storeA,
    storeB: state.storeB   
  }
}, {
  fetchData: commonActions.fetchData
});

class Component extends React.Component {
  static propTypes = {
    storeA: React.PropTypes.object,
    storeB: React.PropTypes.object,
    fetchData: React.PropTypes.func.isRequired
  }

  render() {
    return null;
  }
}

export default componentConnect(Component)

Then in our testing, we can test Component with pure props, by import { WrappedComponent as Component } from '../Component'.

However, we only support Reflux.connect to createStore.

It is similar like this issue mentioned, but use function to create.
How do you think ?

Thanks.

@spoike
Copy link
Member Author

spoike commented Nov 24, 2015

👍 Thanks for your insight @morlay

I'll have to refer to this in the documentation among other HOC/ES6 plugins that have popped up lately on npm, which I'm very happy for, since I'd like to keep reflux and reflux-core small. See e.g. reflux/reflux-core#5, #420 and #225 for other examples.

@BryanGrezeszak
Copy link
Contributor

Not solved in the ways outlined here, but the general concept of ES6 style component implementation instead of mixins is now solved.

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

No branches or pull requests

6 participants