【问题标题】:ExpressJS/ReactJS persistent destructuring problemExpressJS/ReactJS 持久解构问题
【发布时间】:2018-09-25 14:58:13
【问题描述】:

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

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

如果我使用此表示法 this.props.returnedData[0] 访问返回数组中唯一的对象,则会收到返回的数据 [0] 不存在或未定义的错误。

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

我相信这是由于在 React 已经尝试渲染返回的数据 [0] 之后 componentDidMount 返回了数据。

所以,问题。 有没有办法以其他方式解构或访问该数据? 有没有比使用 componentDidMount 检索数据“更好”的方法(关于时间)?

【问题讨论】:

  • console.log 已同步。您可能想使用 console.log(JSON.parse(JSION.stringify(this.props.returnedData))) 并查看问题。从广义上讲,在代码中的某处抛出IF 可以解决问题
  • 是的,元素是在道具有数据之前渲染的,所以你会收到这个错误。检查link 1link 2 来解决这个问题。

标签: reactjs express


【解决方案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); }
        }

dashboard 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 运算符,现在它在保存到Redux 的@ 时变成了一个简单的对象987654346@ 通过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
});

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

结果:

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-26
      • 1970-01-01
      • 2011-01-16
      • 1970-01-01
      • 1970-01-01
      • 2011-10-12
      • 2011-04-04
      • 2017-04-25
      相关资源
      最近更新 更多