Я начал JS в первый раз, не зная его функций. Имея начальные знания JS, я начал ReactJS, который для меня очень нов, наша команда работала над ReactJS с AltJS в качестве потока.
Эта статья предназначена для того, чтобы поделиться хорошей структурой компонентов ReactJS и Flux (AltJS), которую я изучил.
Если вы новичок, следуйте отличной документации ReactJS, AltJS и Redux.

Организация компонентов
Как и в любом коде, важна согласованность. это, конечно, применимо при структурировании ваших компонентов React.
Каждая начальная страница из маршрутов будет находиться в папке Pages, которая будет импортирована в маршруты. затем для каждого независимого компонента следует запускать из папки containers, а дальнейшие компоненты будут разбиваться.

File Structure
--src
---containers
-----exampleContainer.js
-----example2Container.js
---components
-----exampleComponent.js
-----exampleChildComponent.js
---pages
-----examplePage.js
--routes.js

ПримерPage.js

import React, { PropTypes } from 'react';
import ExampleContainer from 'containers/ExampleContainer';
const ExamplePage = (params) =>
  <ExampleContainer
    params={params}
  />;
ExamplePage.propTypes = {
  params: PropTypes.object,
};
module.exports = ExamplePage;

ПримерContainer.js

import React, { PropTypes } from 'react';
import AltContainer from 'alt-container';
import ExampleActions from 'actions/ExampleActions';
import ExampleStore from 'stores/ExampleStore';
import ExampleComponent from 'components/example/ExampleComponent';
class ExampleContainer extends React.Component {
componentDidMount() {
  document.title = 'Container Example';
// this will get the data and rerender the component. while you can show loading.
  ExampleActions.getDate(); 

}
render() {
  return (
   <div>
      <AltContainer store={ExampleStore}>
       <ExampleComponent
         params={this.props.params}
       />
     </AltContainer>
    </div>
   );
  }
}
ExampleContainer.propTypes = {
  params: PropTypes.object,
};
module.exports = ExampleContainer;

ПримерComponent.js

Давайте предположим, что этот компонент является своего рода макетом, который также использует один или несколько компонентов, которые необходимо использовать повторно.

import React, { PropTypes } from 'react';
import Example2Container from 'containers/Example2Container';
import ExampleChildComponent from 'components/example/ExampleChildComponent';
class ExampleComponent extends React.Component {
render() {
    return (
      <div>
        <ExampleChildComponent
          params={this.props.params}
          cages={this.props.cages}
         />        
        <Example2Container
          params={this.props.params}
         />
      </div>
    );
  }
}
ExampleComponent.propTypes = {
  params: PropTypes.object,
  cages: PropTypes.object
};
module.exports = ExampleComponent;

Вышеупомянутый Example2Container будет иметь ту же структуру, и в контейнере его можно будет прикрепить к данным хранилища.

Вышеупомянутая структура React может быть легко присоединена с помощью Flux.
Давайте начнем Flux с Altjs.

With Altjs Structure
--src
---actions
-----exampleAction.js
---containers
---components
---pages
---sources
-----exampleSource.js
---stores
-----exampleStore.js
---utils
-----normalizers
-------exampleNormalizer.js
--routes.js

Поскольку поток является однонаправленным подходом, мы должны строго следовать ему. мы будем вызывать действия только через компоненты или контейнеры, затем из действия мы будем использовать источник, если потребуется взаимодействие с сервером. , ответы сервера будут проходить через функцию normalizer (которая сопоставит необходимые данные с известными ключами, которые будут использоваться в компонентах), а затем преобразовать их в action, теперь action можно привязать к нескольким хранилищам в AltJS для обновления нескольких компонентов с помощью одного действия.

Normalizer будет очень хорошим способом уменьшить усилия в будущем, если ваш API будет обновлен или изменится какая-либо структура.

давайте посмотрим, как этот поток данных должен быть в файлах. используя любой компонент, который я вызываю, exampleAction.getData(); действие, которое будет дополнительно обновлять данные компонентов.

exampleAction.js

import alt from 'AltApp';
import exampleSource from 'sources/exampleSource';
class ExampleActions { 
  constructor() {
    this.generateActions(
      'setData', // this will generate action automatically which only returns given data.
    );
  }
getData() {
  return (dispatch) => {
   dispatch();
   exampleSource.getData().then((response) => {
     this.setData(response);
   });
  };
}
}
export default alt.createActions(ExampleActions);

примерSource.js

import Request from 'superagent';
import { HTTP_HEADERS } from 'utils/Constants';
import normalizeExampleData from 'utils/exampleNormalizer';
const ExampleSource = {
getData() {
    return new Promise((resolve, reject) => {
      const url = 'http://example.com/123';
Request
   .get(url)
   .set(HTTP_HEADERS)
   .end((err, res) => {
      if (err) {
        // error occured
        reject({ text: 'Error Message Here' });
      } else {
         const jsonData = res.body;
         const normalizedData = normalizeExampleData(jsonData);
         resolve({ exampleData:normalizedData });
       }
     });
   });
 },
};
module.exports = ExampleSource;

примерNormalizer.js

// suppose we receive data like below
/*
{
birdsInCage:[
  {name:'parrot',color:'green'},
  {name:'eagle',color:'white'}
  ]
}
*/
export const normalizeExampleData = (response) => {
  //in case it received empty  || [] will guarantee it will be array
  (response || []).map( (cage) =>
    ({
      birdName:cage.name,
      birdColor:cage.color,
    });
  );
}

Теперь этот нормализатор отправит данные обратно в источник, источник передаст их действию, а действие отправит их в хранилище.

exampleStore.js

import Alt from 'AltApp';
import ExampleAction from 'actions/exampleAction';
class ExampleStore {
constructor() {
    this.initializeStore();
    this.bindActions(ExampleAction);
initializeStore() {
    this.cages = {};
  }
onSetData(data) {
    this.cages = data;
  }
}
module.exports = Alt.createStore(ExampleStore, 'ExampleStore');

Теперь эти данные будут переданы в exampleComponent через exampleContainer с использованием AltContainer.

Эта структура react + Flux позволяет легко вносить изменения с помощью независимых компонентов. Действия React, Actions, Sources и Normalizer также можно использовать в Redux.

Советы:

Не используйте Inline CSS.
Используйте ESLint в своем проекте, чтобы следовать стандартам.
Не используйте Refs для обновления состояния компонентов.
Используйте Normalizer, это обезопасит вас в будущем.
Не замыкайте поток, это сильно навредит вам.

Вывод:

Эти рекомендации ни в коем случае не являются авторитетными или исчерпывающими, но я считаю, что они являются хорошей отправной точкой для организации и стандартизации компонентов React и некоторых наиболее распространенных вариантов использования, с которыми я сталкиваюсь.

Надеемся, что эти рекомендации послужат полезной отправной точкой для организации ваших компонентов React. Обязательно оставьте комментарий, если у вас есть вопрос!