Поток данных React/Reflux: один компонент дважды в DOM

Предположим, у меня есть следующее дерево:

<LandingPage>
    <PageHeader>
        <Menu>
            <ShoppingCart>
        </Menu>
    </PageHeader>
    <MainPage>
        <ShoppingCart>
    </MainPage>
</LandingPage>

Компонент, который нас интересует, - это ShoppingCart.

После его монтирования (componentDidMount) ShoppingCart запускает действие, так что ShoppingCartStore отправляет запрос на сервер и возвращает список статей, вызывая повторное отображение ShoppingCart .

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

Одним из решений было бы иметь общий корневой триггер для этих запросов, но это будет LandingPage - и нужно будет передавать данные через PageHeader, Menu и MainPage.

Есть ли лучшее решение? Это достаточно хорошо?

1 ответ

Решение

Я использую api.store для всех запросов данных. Я вызываю api.store в записи app.js. Затем я использую действие, которое api.store слушает для начальных запросов данных. app.js

'use strict';

import React  from 'react';
import ReactDom  from 'react-dom';

import AppCtrl from './components/app.ctrl.js';
import Actions from './actions/api.Actions';
import ApiStore from './stores/Api.Store';

window.ReactDom = ReactDom;

Actions.apiInit();

ReactDom.render( <AppCtrl />, document.getElementById('react') );
api.store

import Reflux from 'reflux';

import Actions from '../actions/api.Actions';
import ApiFct from '../utils/sa.api';

let ApiStoreObject = {
  newData: {
    "React version": "0.14",
    "Project": "ReFluxSuperAgent",
    "currentDateTime": new Date().toLocaleString()
  },
  listenables: Actions,
  apiInit() { ApiFct.setData(this.newData); },
  apiInitDone() { ApiFct.getData(); },
  apiSetData(data) { ApiFct.setData(data); }
}
const ApiStore = Reflux.createStore(ApiStoreObject);
export default ApiStore;

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

import React from 'react';

import BasicStore from '../stores/Basic.Store';

let AppCtrlSty = {
  height: '100%',
  padding: '0 10px 0 0'
}

const getState = () => {
  return {
    Data1: BasicStore.getData1(),
    Data2: BasicStore.getData2(),
    Data3: BasicStore.getData3()
  };
};

class AppCtrlRender extends React.Component {
   render() {
    let data1 = JSON.stringify(this.state.Data1, null, 2);
    let data2 = JSON.stringify(this.state.Data2, null, 2);
    let data3 = JSON.stringify(this.state.Data3, null, 2);
    return (
      <div id='AppCtrlSty' style={AppCtrlSty}>
        React 0.14 ReFlux with SuperAgent<br/><br/>
        Data1: {data1}<br/><br/>
        Data2: {data2}<br/><br/>
        Data3: {data3}<br/><br/>
      </div>
    );
  }
}

export default class AppCtrl extends AppCtrlRender {
  constructor() {
    super();
    this.state = getState();
  }

  componentDidMount = () => { this.unsubscribe = BasicStore.listen(this.storeDidChange); };
  componentWillUnmount = () => { this.unsubscribe(); };
  storeDidChange = (id) => {
    switch (id) {
      case 'data1': this.setState({Data1: BasicStore.getData1()}); break;
      case 'data2': this.setState({Data2: BasicStore.getData2()}); break;
      case 'data3': this.setState({Data3: BasicStore.getData3()}); break;
      default: this.setState(getState());
    }
  };
}

С https://github.com/calitek/ReactPatterns React.14 / ReFluxSuperAgent.

Другие вопросы по тегам