在React中创建表给出错误-元素类型无效

时间:2018-10-18 14:09:03

标签: reactjs

当我将简单的map函数与下面显示的数据一起使用时,我通常会创建表的行和列,效果很好:

const tableRows = [
      {
        name: 'SickLeave difference',
        januaryPayment: '-12000',
        febrauaryPayment: '0',
      },
      {
        name: 'Holiday difference',
        januaryPayment: '10000',
        febrauaryPayment: '25000',
      },
      {
        name: 'Result',
        januaryPayment: '0',
        febrauaryPayment: '23000',
      },
    ];

    <Table headerTextCodes={headerTextCodes} allowFormattedHeader={false}>
      { tableRows.map(row => (
        <TableRow>
          <TableColumn>
            { row.name }
          </TableColumn>
          <TableColumn>
            { row.januaryPayment }
          </TableColumn>
          <TableColumn>
            { row.febrauaryPayment }
          </TableColumn>
        </TableRow>
      ))
      }
    </Table>

但是,当我尝试通过首先格式化当前正在模拟的结果作为后端响应的格式来创建要在其中创建数据的表行和列时:

const result = {
      periodFrom: '2018-05-01',
      periodTo: '2018-07-31',
      sumDifference: 17873,
      periodsPerReceiver: [
        {
          receiverType: {
            code: 'ARBG_PRIV',
            name: null,
          },
          resultsPerMonth: [
            {
              from: '2018-05-01',
              to: '2018-05-31',
              resultPerField: [
                {
                  fieldCode: {
                    code: 'SP',
                    name: null,
                  },
                  previouslyPayed: 0,
                  newAmount: 2662,
                  difference: 2662,
                },
              ],
              isNewPaymentPeriod: false,
            },
            {
              from: '2018-06-01',
              to: '2018-06-30',
              resultPerField: [
                {
                  fieldCode: {
                    code: 'FP',
                    name: null,
                  },
                  paid: 6899,
                  newAmount: 0,
                  difference: -6899,
                },
              ],
              isNewPaymentPeriod: false,
            },
            {
              from: '2018-07-01',
              to: '2018-07-31',
              resultPerField: [
                {
                  fieldCode: {
                    code: 'FP',
                    name: null,
                  },
                  paid: 0,
                  newAmount: 20012,
                  difference: 20012,
                },
              ],
              isNewPaymentPeriod: false,
            },
          ],
        },
        {
          receiverType: {
            code: 'BRUKER',
            name: null,
          },
          resultsPerMonth: [
            {
              from: '2018-05-01',
              to: '2018-05-31',
              resultPerField: [
                {
                  fieldCode: {
                    code: 'FP',
                    name: null,
                  },
                  paid: 0,
                  newAmount: 0,
                  difference: 0,
                },
              ],
              isNewPaymentPeriod: false,
            },
            {
              from: '2018-06-01',
              to: '2018-06-30',
              resultPerField: [
                {
                  fieldCode: {
                    code: 'FP',
                    name: null,
                  },
                  paid: 0,
                  newAmount: 2098,
                  difference: 2098,
                },
              ],
              isNewPaymentPeriod: false,
            },
            {
              from: '2018-07-01',
              to: '2018-07-31',
              resultPerField: [
                {
                  fieldCode: {
                    code: 'FP',
                    name: null,
                  },
                  paid: 0,
                  newAmount: 0,
                  difference: 0,
                },
              ],
              isNewPaymentPeriod: false,
            },
          ],
        },
      ],
    };

我已经创建了此函数来构造数据,以便稍后可以在渲染函数中使用它来创建表和表行:

const resultPerReceiver = (receiver) => {
  const receiverObject = {
    receiver: receiver.receiverType,
    fields: [],
  };

  receiver.resultsPerMonth.forEach((monthResult) => {
    monthResult.resultPerFields.forEach((resultPerField) => {
      const fieldExists = receiverObject.field.find(e => e.field.code === resultPerField.fieldCode.code);
      if (fieldExists) {
        fieldExists.rows.forEach((row) => {
          const rowExists = row.resultPerMonth.find(e => e.from === monthResult.from);
          if (!rowExists) {
            const newAmount = {
              from: monthResult.from,
              to: monthResult.to,
              amount: resultPerField.newAmount,
            };
            const paid = {
              from: monthResult.from,
              to: monthResult.to,
              amount: resultPerField.paid,
            };
            const difference = {
              from: monthResult.from,
              to: monthResult.to,
              amount: resultPerField.difference,
            };
            fieldExists.rows.find(e => e.name === 'newAmount').resultPerMonth.push(newAmount);
            fieldExists.rows.find(e => e.name === 'paid').resultPerMonth.push(paid);
            fieldExists.rows.find(e => e.name === 'difference').resultPerMonth.push(difference);
          }
        });
      } else {
        receiverObject.field.push({
          field: resultPerField.fieldCode,
          rows: [
            {
              name: 'newAmount',
              resultPerMonth: [
                {
                  from: monthResult.from,
                  to: monthResult.to,
                  amount: resultPerField.newAmount,
                },
              ],
            },
            {
              name: 'paid',
              resultPerMonth: [
                {
                  from: monthResult.from,
                  to: monthResult.to,
                  amount: resultPerField.paid,
                },
              ],
            },
            {
              name: 'difference',
              resultPerMonth: [
                {
                  from: monthResult.from,
                  to: monthResult.to,
                  amount: resultPerField.difference,
                },
              ],
            },
          ],
        });
      }
    });
  });

  return receiverObject;
};

const formattedResult = result.periodsPerReceiver.map(receiver => resultPerReceiver(receiver));

得到的结果看起来像这样:

const formattedResult = [ 
  {
    receiver: {code: "ARBG_PRIV", name: null },
    fields: [
      { field: { code: "SP", name: null },
        rows: [
          {name: "newAmount", resultPerMonth: [
              {from: "2018-06-01", to: "2018-06-31", amount: 2662},
              {from: "2018-07-01", to: "2018-07-31", amount: 2662}
            ]
          },
          {name: "paid", resultPerMonth: [
              {from: "2018-06-01", to: "2018-06-31", amount: 2662},
              {from: "2018-07-01", to: "2018-07-31", amount: 2662}
            ]
          },
          {name: "difference", resultPerMonth: [
              {from: "2018-06-01", to: "2018-06-31", amount: 2662},
              {from: "2018-07-01", to: "2018-07-31", amount: 2662}
            ]
          }
        ]
      },
      { field: { code: "FP", name: null },
        rows: [
          {name: "newAmount", resultPerMonth: [
              {from: "2018-06-01", to: "2018-06-31", amount: 2662},
              {from: "2018-07-01", to: "2018-07-31", amount: 2662}
            ]
          },
          {name: "paid", resultPerMonth: [
              {from: "2018-06-01", to: "2018-06-31", amount: 2662},
              {from: "2018-07-01", to: "2018-07-31", amount: 2662}
            ]
          },
          {name: "difference", resultPerMonth: [
              {from: "2018-06-01", to: "2018-06-31", amount: 2662},
              {from: "2018-07-01", to: "2018-07-31", amount: 2662}
            ]
          }
        ]
      },
    ]
  },
  {
    receiver: {code: "BRUKER", name: null },
    fields: [
      { field: { code: "SP", name: null },
        rows: [
          {name: "newAmount", resultPerMonth: [
              {from: "2018-06-01", to: "2018-06-31", amount: 2662},
              {from: "2018-07-01", to: "2018-07-31", amount: 2662}
            ]
          },
          {name: "paid", resultPerMonth: [
              {from: "2018-06-01", to: "2018-06-31", amount: 2662},
              {from: "2018-07-01", to: "2018-07-31", amount: 2662}
            ]
          },
          {name: "difference", resultPerMonth: [
              {from: "2018-06-01", to: "2018-06-31", amount: 2662},
              {from: "2018-07-01", to: "2018-07-31", amount: 2662}
            ]
          }
        ]
      },
      { field: { code: "FP", name: null },
        rows: [
          {name: "newAmount", resultPerMonth: [
              {from: "2018-06-01", to: "2018-06-31", amount: 2662},
              {from: "2018-07-01", to: "2018-07-31", amount: 2662}
            ]
          },
          {name: "paid", resultPerMonth: [
              {from: "2018-06-01", to: "2018-06-31", amount: 2662},
              {from: "2018-07-01", to: "2018-07-31", amount: 2662}
            ]
          },
          {name: "difference", resultPerMonth: [
              {from: "2018-06-01", to: "2018-06-31", amount: 2662},
              {from: "2018-07-01", to: "2018-07-31", amount: 2662}
            ]
          }
        ]
      },
    ]
  },
]

然后,我正在尝试通过render函数中的类似函数来渲染此结果:

<div className={styles.table}>
  {
    formattedResult.map(reciever => (
      <Table>
        { reciever.fields.map(field => field.rows.map(row => (
          <TableRow>
            <TableColumn>
              <Image
                tabIndex="0"
                className={styles.expandButton}
                src={arrowDownImageUrl}
                altCode="Timeline.openData"
              />
              { row.name }
            </TableColumn>
            { row.resultPerMonth.map(month => (
              <TableColumn>
                { month.amount }
              </TableColumn>
            ))}
          </TableRow>
        )))}
      </Table>
    ))}
</div>

但是,当我尝试这样做时,出现错误:

  

不变违反:元素类型无效:预期为字符串(对于   内置组件)或类/函数(用于复合组件)   但得到:未定义。您可能忘记了从中导出组件   定义的文件,或者您可能混淆了默认文件并命名为   进口。在体内(由表格创建)

我已经检查了组件中的所有导入,并且正在正确导入它们,因为在渲染上面显示的简单数据时不会发生此错误。我不知道为什么在后一种情况下会发生这种情况,我做错了什么?

Here,您可以看到它的沙箱。

1 个答案:

答案 0 :(得分:3)

在第二种情况下,您使用的是forEach,它返回undefined。 您应该使用map来获取数组。

要小心,您将获得一个数组数组。也许您应该使用lodash或散布运算符中的flatMap