Я новичок в React, и моя проблема заключается в следующем: у меня есть компонент, называемый IncExpSummary, который показывает общую сумму доходов и расходов. Он получает данные о доходах и расходах из избыточного магазина с помощью «mapStateToProps». У меня также есть селекторная функция под названием «total», которая отображает массив объектов и возвращает total (эта функция работает нормально). Проблема в том, что каждый раз, когда я добавляю новый доход или расход, общая сумма не рассчитывается, но сумма нового элемента добавляется в конце предыдущего числа.

IncExpSummary выглядит так:

import React from 'react';
import { connect } from 'react-redux';
import total from '../selectors/total.js';

class IncExpSummary extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div>
        <div className="income-summary">
          <p className="income-summary-text">Income: {this.props.totalIncome}</p>

        </div>
        <div className="expense-summary">
          <p className="expense-summary-text">Expense: {this.props.totalExpense}</p>

        </div>
      </div>
    )
  }
}

function mapStateToProp(state) {
  return {
    totalIncome: total(state.income),
    totalExpense: total(state.expenses)
  }
}

export default connect(mapStateToProp)(IncExpSummary);

Функция total выглядит следующим образом:

export default (data) => {
  if (data.length > 0) {
    return data.map((item) => {
      return item.amount;
    }).reduce((total, amount) => {
      return total + amount;
    });
  } else {
    return 0;
  }
}

После добавления двух доходов с количеством 30 и 20 каждый я ожидал, что результат будет 50, но фактический результат - 3020.

Полный проект доступен здесь: https://codesandbox.io/s/l4k6q6ok5q

0
ubaid 1 Май 2019 в 10:19

3 ответа

Лучший ответ

Это потому, что значения item.amount являются строками. Это приводит к конкатенации строк.

Измените его на следующее, чтобы строки были проанализированы как числа с плавающей точкой, и они будут работать правильно:

export default (data) => {
  if (data.length > 0) {
    return data.map((item) => {
      return parseFloat(item.amount);
    }).reduce((total, amount) => {
      return total + amount;
    });
  } else {
    return 0;
  }
}
3
leroydev 1 Май 2019 в 07:21

Вам нужно разобрать номер:

export default (data) => {
  if (data.length > 0) {
    return data.map(({ amount }) => parseFloat(amount)).reduce((total, amount) => total + amount);
  } else {
    return 0;
  }
}
0
Jack Bashford 1 Май 2019 в 07:23

Просто измените строку в функции 'total', не возвращая сумму строки:

return item.amount;

Ниже для возврата целого числа:

return +item.amount;
0
Murtaza Hussain 1 Май 2019 в 08:23