A
A
Alexander Wolf2015-12-21 16:41:05
JavaScript
Alexander Wolf, 2015-12-21 16:41:05

How to properly break code into components?

Good afternoon! I began to actively study React and ran into a very interesting question: how exactly to divide the code into components? I must say right away that I really liked the component approach, however, it is quite difficult to move away from MVC, therefore I am asking this question here.
For example, I have a page that displays the results of a contest. Its render function is too fat (in my opinion) and I would like to break it into smaller parts. However, I don't really know how to do it. I mean, divide so that it makes sense. So you can just break it into 3-4 parts, then glue it together. However, in this case, I will not use the full power of the components - reusability.
Page example:

spoiler
var formResults = React.createClass({
  mixins: [ReactMeteorData],

  getMeteorData() {
    return {
      stats: FormStats.find({ form: this.props._id }).fetch(),
      percent: (FormStats.find({ form: this.props._id }).count() / this.props.viewed).toFixed(2) * 100,
      ended: FormStats.find({ form: this.props._id }).count(),
      average: this.average(),
      charts: Forms.findOne(this.props._id).items.filter(item => {
        var items = ['checkbox', 'dropdown', 'rating'];
        return items.indexOf(item.type) > -1;
      })
    };
  },
  getInitialState() {
    return {
      page: 0
    };
  },

  t() {
    return App.lang.t(...arguments);
  },
  average() {
    var res = [];

    FormStats.find({ form: this.props._id }).map(function(stat) {
      res.push(stat.createdAt - stat.from);
    });

    var dur = moment.duration(lodash.sum(res) / res.length);

    return [dur.minutes(), dur.seconds()].map(i => i < 10 ? '0' + i : i).join(':');
  },
  date(item) {
    return moment(item.createdAt).format('L')
  },
  getPageClass(id) {
    var str = 'info panel panel-default';
    if(this.state.page != id) str += ' hidden';

    return str;
  },
  setPage(id) {
    return (e) => {
      this.setState({ page: id });
    };
  },
  isActive(id) {
    return this.state.page == id && 'active';
  },
  chartConfig(chart) {
    console.log(chart);

    return {};
  },
  render() {
    return <div id="form" className="container">
      <Steps />
      <div id="questions" className="stat">
        <h3>
          {this.props.name}
        </h3>
        <div className="row">
          <div className="col-xs-6">
            <Progress percent={this.data.percent} />
          </div>
        </div>
        <div className="row">
          <div className="col-xs-3">
            <Statistic
              title={this.props.viewed}
              message={this.t('polls.stat.started')} />
          </div>
          <div className="col-xs-3">
            <Statistic
              title={this.data.ended}
              message={this.t('polls.stat.ended')} />
          </div>
          <div className="col-xs-3">
            <Statistic
              title={this.data.average}
              message={this.t('polls.stat.average')} />
          </div>
          <div className="col-xs-3">
            <Statistic
              title={0}
              message={this.t('polls.stat.clicked')} />
          </div>
        </div>
        <div className="row">
          <div className="col-xs-12">
            <ul className="nav nav-tabs nav-justified panelled">
              <li
                className={this.isActive(0)}
                onClick={this.setPage(0)}>
                <a href="#results">Результаты</a>
              </li>
              <li
                className={this.isActive(1)}
                onClick={this.setPage(1)}>
                <a href="#stat">Статистика</a>
              </li>
            </ul>
            <div className={this.getPageClass(0)}>
              <div className="panel-content">
                {this.data.stats.map(item => {
                  var path = Router.path('form/result', { _id: this.props._id, result: item._id });

                  return <div className="row" key={item._id}>
                    <div className="col-xs-4">
                      {item.ip}
                    </div>
                    <div className="col-xs-4">
                      {this.date(item)}
                    </div>
                    <div className="col-xs-4">
                      <a href={path}>Результаты</a>
                    </div>
                  </div>;
                })}
              </div>
            </div>
            <div className={this.getPageClass(1)}>
              {this.data.charts.map(chart => {
                return <Highcharts key={chart._id} config={this.chartConfig(chart)} />;
              })}
            </div>
          </div>
        </div>
      </div>
    </div>;
  }
});

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Andrey Antropov, 2015-12-21
@mannaro

In order to make sense in the resulting components, you can go, for example, from design, that is, take and simply divide the page design into logical blocks, these will be the largest containers, then start highlighting logically separated or repeating elements in them.
This process can be repeated for a very long time, but it is important to stop at a moment when it no longer bears a logical basis.
I also recommend looking at the atomic design approach,
This is an article from a design point of view sketchapp.me/verstka-sajta-s-pomoshhyu-sketch-i-at...
This is from the organization side bradfrost.com/blog/post/atomic-web- design
Not tied to React, but fits well with it.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question