LINUX.ORG.RU

React+Redux, быстро растет «бесполезный» код

 ,


0

2

Есть контейнер, который подключен к Redux'у. Этот контейнер, по сути, управляет всем приложением.

Метод в моем контейнере, который возвращает модальное окно «ModalPostSelect»:

createModalPostSelect(callbackOpen, callbackClose, callbackSelectPost, callbackPostExportStart, callbackLoadCheckLoop, posts) {
  const startExport = (postId) => {
    callbackSelectPost(postId);
    callbackPostExportStart();
    callbackLoadCheckLoop();
    callbackOpen(MODAL_EXPORT_PROGRESS);
  };
  return <ModalPostSelect
    callbackClose={callbackClose} 
    callbackPostSelect={startExport}
    posts={posts}
  />;
}
Обратите внимание на то, сколько у метода параметров. Уже здесь у меня закрадываются подозрения, что что-то идет не так... Слишком уж их много.

Часть метода render контейнера:

{ this.props.modals.current === MODAL_POST_SELECT && this.createModalPostSelect(
  this.props.actionModalOpen,
  this.props.actionModalClose,
  this.props.actionCommentsLoadSelectPost,
  this.props.actionCommentsLoadStart,
  this.props.actionCommentsLoadCheckLoop,
  this.props.commentsLoad.posts
) }

В чем, собственно, проблема - на сколько я понимаю, «правильно» передавать все необходимое для работы метода в качестве параметров, это облегчает тестирование, позволяет создавать чистые функции и т.д.

Но как быть, блин, с таким количеством бесполезного кода? Сначала передаем 6 параметров в метод, а потом еще и в самом методе тупо передаем данные/колбеки дальше. Бред же? Как упростить и сократить код, не растеряв при этом его качества?

Deleted
Ответ на: комментарий от vcerloman

Ахренеть, колхозники не осилил трейс?

Трейс в реактоподелках бесполезен. Он будет полностью засран не тем, чем надо.

crutch_master ★★★★★
()
Ответ на: комментарий от crutch_master

Эта колхоз-поделка, которую мы обсуждаем, - это и есть трейс вызова одной функции. А т.к. все события проходят через эту одну функцию - она трейсит все события.

vcerloman
()

Чтобы упростить тестирование вполне достаточно того, чтобы в компоненте не было своего state.

Реакт компонент сам по себе уже функция, сигнатура которой (props) => {} ( на самом деле (props, context) => {}, но это другая тема). В связи с этим в основном функция генератор лишняя. Компонент должен оставаться чист и непорочен по возможности, но быть connected к как угодно сложному state.

Далее - контейнер управляющий приложением это както не кул - приложением должно управлять состояние.

Идея react+redux в том, что бизнес логика должна располагаться в actions and reducers (которые по сути обновляют state, потому state первичен), компоненты лишь отображают текущий redux state.

Допустим код TC может быть вот таким

// описываем сложные взаимные связи компонентов в actions,
// всякая логика связаная с promise chains должна происходить в actions
// в redux state по мере возможности лучше класть только сериализируемые данные

const selectPost = (postId) => {
  return (dispatch) => {
     dispatch(selectPost(postId));
     dispatch(exportStart(postId));
     dispatch(checkLoop(postId));
  };
};
// Имплементация среднестатистического редукс компонента
const stateToProps = (state) => {
  currentModal: state.modals.current
}

const dispatchToProps = (dispatch) => {
  return {
    dispatch,
  };
}

@connect(stateToProps, dispatchToProps)
export class SelectPostsModal extends React.Component {

  ...
  
  renderPost(post){
    const { dispatch, selectPost } = this.props;
    return <div className='post'>
       <div onClick={() => selectPost(post.id)(dispatch)}>Select Post</div>
       <div> {JSON.stringify(post)} </div>
    </div>
  }
  render() {
    const { dispatch, closeModal } = this.props;
    return (
    <Modal 
        isHidden={this.props.currentModal === MODAL_POST_SELECT} 
        close={() => dispatch(closeModal())
    ><Modal.Body>
        {posts && posts.map(this.renderPost)}
      </Modal.Body> 
    <Modal>
  ); 
// С помощью enzyme можем написать тест для SelectPostsModal
// [url=https://github.com/airbnb/enzyme] enzyme(render, mount, shallow)[/url].

import { SelectPostsModal } from './....'; // не connected версия компонента

import { expect } from 'chai';
import { shallow } from 'enzyme';

descibe('Select posts modal component') {
  it('should be hidden if not current', () => {
       const wrapper = shallow(<SelectPostsModal
               posts={[{ id: 10 }]}
               currentModal='MY_MODAL'
               dispatch={() => {}}
       />);

       expect(wrapper.find('.post')).to.have.length(0);
  })
}

Boui
()
Ответ на: комментарий от anonymous

Мне иногда начинает казаться, что царь удаляется на некоторое время, досконально изучает что-то новенькое, а потом приходит обратно на лор, чтобы хорошенько мокнуть, лоровских снобов, много о себе мнящих. Лоровским снобам припекает от того, что их в очередной раз мокнули, они банят царя и трут пруфы своей некомпетентности. Круг замыкается.

kremator666
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.