首页 文章

ExpressJS / ReactJS持续解构问题

提问于
浏览
0

我正在使用ReactJS,ExpressJS,NodeJS,PostgreSQL和Redux

我正在尝试通过axios调用从后端检索一行SQL表 . 该调用在嵌套在数组 [{..}] 中的对象中返回所请求的数据 . 当我尝试解构数据或通过括号表示法访问数据时,会出现问题 .

如果我使用这种表示法 this.props.returnedData[0] 来访问返回数组中唯一的对象,我会得到RETData [0]不存在或未定义的错误 .

请记住,我可以看到它实际上已经通过console.log返回数组中的数据 .

我相信这是因为在React已经尝试渲染返回的数据[0]之后,componentDidMount返回数据 .

所以,问题 . 有没有办法以任何其他方式构造或访问该数据?与使用componentDidMount相比,检索数据是否有“更好”的方式(关于时间)?

2 回答

  • 1

    请原谅冗长的解释,但它显示了所有步骤......

    让我们来看看这个例子:用户进入 Dashboard 视图......

    client/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/DashboardPanelsDashboardPanels 组件已挂载,然后在其 componentDidMount 生命周期方法中执行传递的Redux getDashboardData() 操作 - 注意:如果尚未填充数据,则显示一个微调器!)

    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 (这会向 express API服务器发出AJAX请求)

    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
    }
    

    routes/dashboard.js (前端AJAX请求命中 express API服务器的仪表板路由 - 通过身份验证,然后被发送到 getAll 控制器)

    const { getAll } = require('../controllers/dashboard);
        const { requireRelogin, requireAuth } = require('../services/strategies');
    
        app.get('/api/dashboard', requireAuth, getAll);
    }
    

    controllers/dashboard.jsgetAll 控制器接收请求,查询PostgresSQL数据库并返回 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/reducers/index.js (但是,因为我们将 res.send()...spread 运算符一起使用,它现在变为一个简单的对象,当它通过 dashboardReducer 保存到Redux的 state 时)

    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
    });
    

    Redux的 dashboard 状态现在结构如下:

    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 通过 HOC 组件连接到Redux,我们现在可以通过 this.props.dashboardData 访问Redux的 state.dashboard.data .

    结果如下:

    enter image description here

  • 1

    如果我正确理解了该问题,您将尝试访问不存在的数组索引,因为您的数据尚未到达 . 解决此问题的一种方法可能是在访问数组之前快速检查数组是否有索引 . 像这样的东西:

    const data = this.props.returnedData.length > 0 ? this.props.returnedData[0]: {}
    

    然后进一步使用新的“数据”变量,例如在渲染方法或类似方法中 .

相关问题