kadirahq / mantra

Mantra - An Application Architecture for Meteor
https://kadirahq.github.io/mantra/
976 stars 50 forks source link

container components vs composers... #49

Open makstr opened 8 years ago

makstr commented 8 years ago

@arunoda so I have been thinking about the container components approach and realized that sometimes the containers could be abstracted to more universal composer functions and later combined in a more 'on demand' manner.

Take a look at the _colors module

I have the following structure:

I also have the data rendering / functional components:

and instead of using containers I have a abstract list of composers function:

/_colors/composers/colors/edit.jsx:


import {useDeps} from 'react-simple-di';
import {composeWithTracker, composeAll} from 'react-komposer';

import {singleComposer} from './single.jsx';

export const editComposer = ({context, clearErrors}, onData) => {
  const {LocalState} = context();
  const error = LocalState.get('_colors.SAVING_ERROR');
  onData(null, {error});

  // clearErrors when unmounting the component
  return clearErrors;
};

export const depsMapper = (context, actions) => ({
  submitAction: actions._colors.update,
  clearErrors: actions._colors.clearErrors,
  context: () => context
});

export default (component) => composeAll(
    composeWithTracker(singleComposer),
    composeWithTracker(editComposer),
    useDeps(depsMapper)
  )(component);

/_colors/components/colors/edit.jsx:

import React from 'react';
import Sidebar from './_sidebar.jsx';

// import Container from '../../containers/colors/edit.jsx';
import dataComposer from '../../composers/colors/edit.jsx';
import Component from './_form.jsx';
const Container = dataComposer(Component);

export default class extends React.Component {

  render() {
    const {_id} = this.props;
    return (
      <div className="bs-docs-section clearfix">
        <div className="row">
          <div className="col-md-3">
            <Sidebar />
          </div>
          <div className="col-md-9">
            <Container _id={_id}/>
          </div>
        </div>
      </div>
    );
  }
}
view / composer collection single add edit
collection X
single X X
add X
edit X

Of course if you want ready to use container components nothing is stopping you and they will be even simpler to write given a set of well designed composer functions.

/_colors/containers/colors/edit.jsx:

import dataComposer from '../../composers/colors/edit.jsx';
import Component from '../../components/colors/_form.jsx';
export default dataComposer(Component);

Benefits?

What do you think?

arunoda commented 8 years ago

I think this is a big topic we should discuss. So, I defer this until we ship module system.

But, If it's the composers directory, we should only place the composer function only. May be these should go into the library directory.