Извините за длинное объяснение, но оно показывает все шаги ...
Давайте рассмотрим этот пример: пользователь переходит к Dashboard
представлению ...
клиенту/src/containers/dashboard.js (этот контейнер HOC
в основном просто передает действия и состояние Redux компоненту DashboardPanels
.)
import React from 'react';
import { connect } from 'react-redux';
import { getDashboardData } from '../actions/dashboardActions';
import DashboardPanels from '../components/dashboard/DashboardPanels';
export default connect(state => ({ dashboardData: state.dashboard.data }), { getDashboardData })(props => <DashboardPanels {...props} />)
client / src / components /dashboard / DashboardPanels (компонент DashboardPanels
монтируется, а затем выполняет переданное действие Redux getDashboardData()
в своем методе жизненного цикла componentDidMount
- ВНИМАНИЕ: если данные еще не заполнены, он показывает счетчик!)
import React, { Component } from 'react';
import { Row } from 'antd';
import PageContainer from '../app/panels/pageContainer';
import MessagesPanel from './messagesPanel';
import PlansPanel from './plansPanel';
import PromotionalsPanel from './promotionalsPanel';
import Spinner from '../app/loaders/Spinner';
import SubcribersPanel from './subscribersPanel';
import TemplatesPanel from './templatesPanel';
import TransactionsPanel from './transactionsPanel';
export default class Dashboard extends Component {
componentDidMount = () => this.props.getDashboardData();
render = () => (
!this.props.dashboardData
? <Spinner />
: <PageContainer>
<Row style={{ marginTop: 30 }}>
<SubcribersPanel {...this.props.dashboardData} />
<PlansPanel {...this.props.dashboardData} />
<PromotionalsPanel {...this.props.dashboardData} />
<TransactionsPanel {...this.props.dashboardData} />
<MessagesPanel {...this.props.dashboardData} />
<TemplatesPanel {...this.props.dashboardData} />
</Row>
</PageContainer>
)
}
client / src / actions / dashboardActions.js (это делает запрос AJAX серверу API express
)
import { app } from './axiosConfig';
import * as types from './types';
const getDashboardData = () => dispatch => (
app.get(`dashboard`)
.then(({data}) => dispatch({ type: types.SET_DASHBOARD_DATA, payload: data }))
.catch(err => dispatch({ type: types.SERVER_ERROR, payload: err }))
)
export {
getDashboardData
}
маршруты / dashboard.js (запрос AJAX внешнего интерфейса обращается к маршруту панели инструментов сервера API express
- проходит проверку подлинности, затем отправляется на контроллер getAll
)
const { getAll } = require('../controllers/dashboard);
const { requireRelogin, requireAuth } = require('../services/strategies');
app.get('/api/dashboard', requireAuth, getAll);
}
controllers / dashboard.js (контроллер getAll
получает запрос, запрашивает базу данных PostgresSQLnd возвращает JSON
или то, что вы называете вложенным объектом в массиве [{...}]
.Обратите внимание, что я использую res.send()
с оператором ...spread
!)
const { db, query: { getAllDashboardDetails }} = require('../database);
const { beginofMonth, endofMonth, parseStringToNum, sendError } = require('../shared/helpers');
// GETS ALL DASHBOARD DATA
exports.getAll = async (req, res, done) => {
const beginMonth = beginofMonth();
const endMonth = endofMonth();
try {
const dashboard = await db.many(getAllDashboardDetails, [req.session.id, beginMonth, endMonth])
return res.status(201).send(...dashboard);
} catch (err) { return sendError(err, res, done); }
}
панель управления JSON
имеет такую же структуру на серверной части:
dashboard [{
subscribers: '146',
inactivesubscribers: '12',
plans: '12',
popularplans: [ [Object], [Object], [Object], [Object], [Object], [Object] ],
promotionals: '12',
popularpromotionals: [ [Object], [Object], [Object], [Object], [Object], [Object] ],
credits: '5',
creditstotal: '149.95',
dues: '5',
duestotal: '149.95',
charges: '7',
chargestotal: '209.93',
refunds: '7',
refundstotal: '209.93',
messages: '5',
activetemplates: '4',
inactivetemplates: '4'
}]
client / src / redurs / index.js (однако, поскольку мы использовали res.send()
с оператором ...spread
, теперь он становится простым объектом к моменту сохранения в state
Redux через dashboardReducer
)
import { routerReducer as routing } from 'react-router-redux';
import { combineReducers } from 'redux';
import * as types from '../actions/types';
const dashboardReducer = (state = {}, { payload, type }) => {
switch (type) {
case types.SET_DASHBOARD_DATA:
return {
...state,
data: payload
};
default: return state;
}
}
export default = combineReducers({
dashboard: dashboardReducer,
routing
});
Состояние dashboard
в Redux теперь структурировано так:
dashboard: {
data: {
subscribers: '146',
inactivesubscribers: '12',
plans: '12',
popularplans: [ [Object], [Object], [Object], [Object], [Object], [Object] ],
promotionals: '12',
popularpromotionals: [ [Object], [Object], [Object], [Object], [Object], [Object] ],
credits: '5',
creditstotal: '149.95',
dues: '5',
duestotal: '149.95',
charges: '7',
chargestotal: '209.93',
refunds: '7',
refundstotal: '209.93',
messages: '5',
activetemplates: '4',
inactivetemplates: '4'
}
}
Поскольку DashboardPanels
подключен к Redux через компонент HOC
, мы можемтеперь доступ к Redux state.dashboard.data
через this.props.dashboardData
.
И результат: