Лучший способ использовать уменьшение с реагирующими крючками - PullRequest
0 голосов
/ 17 мая 2019
import React, { memo, useEffect, useMemo, useState } from 'react'
import PropTypes from 'prop-types'
import _ from 'lodash'

import styles from './styles'

import messages from './messages'

import Typography from '@material-ui/core/Typography'

import * as constant from 'constants/players'

import compose from 'hoc/compose'
import withStyles from 'hoc/withStyles'
import withIntl from 'hoc/withIntl'

import InfoPaper from 'components/Paper/Info'

const TotalBalance = memo((
  {
    classes: {
      width,
      head,
      typography
    },
    intl: {
      formatMessage
    },
    wallets,
    player: { amount }
  }
) => {
  const [list, setIList] = useState({
    balance: {
      property: formatMessage(messages.realMoney),
      data: 0
    },
    pendingWinnings: {
      property: formatMessage(messages.pendingWinning),
      data: 0
    },
    bonusBalance: {
      property: formatMessage(messages.bonusMoney),
      data: 0
    },
    commonWallet: {
      property: formatMessage(messages.commonWallet),
      data: 0
    },
    totalBonusWallet: {
      property: formatMessage(messages.totalBonusWallet),
      data: 0
    }
  })

  useEffect(() => {
    setIList((wallets || []).reduce((previous, current) => (
      {
        balance: {
          ...previous.balance,
          data: previous.balance.data + current[constant.balance]
        },
        pendingWinnings: {
          ...previous.pendingWinnings,
          data: previous.pendingWinnings.data + current[constant.pendingWinnings]
        },
        bonusBalance: {
          ...previous.bonusBalance,
          data: previous.bonusBalance.data + current[constant.bonusBalance]
        },
        commonWallet: {
          ...previous.commonWallet,
          data: current.isMain
            ? previous.commonWallet.data + current[constant.commonWallet]
            : previous[constant.commonWallet].data
        },
        totalBonusWallet: {
          ...previous.totalBonusWallet,
          data: previous[constant.totalBonusWallet].data +
            (
              current[constant.balance] +
              current[constant.pendingWinnings] +
              current[constant.bonusBalance]
            )
        }
      }
    ), list))
  }, [wallets])

  const Header = useMemo(() => (
    <div className={head}>
      <Typography
        variant={'h4'}
        className={typography}
      >
        {formatMessage(messages.totalBalance)}
      </Typography>
      <Typography
        variant={'h4'}
        className={typography}
      >
        {amount}
      </Typography>
    </div>
  ), [amount])

  return (
    <InfoPaper
      list={_.values(list)}
      width={width}
      header={Header}
    />
  )
})

TotalBalance.propTypes = {
  wallets: []
}

TotalBalance.propTypes = {
  player: PropTypes.object.isRequired,
  wallets: PropTypes.array
}

export default compose(
  withStyles(styles),
  withIntl()
)(TotalBalance)

У меня есть какой-то компонент, который я хочу переписать, но я не вижу лучшего способа сделать это. У меня есть некоторое начальное состояние (некоторые значения по умолчанию, которые я устанавливаю в функции setState). И затем, когда я получаю массив wallets, я хочу пересчитать это начальное состояние в зависимости от функции reduce. Я хочу сделать это, используя концепцию immutable. Как я вижу, я беру каждый объект в массиве и += предыдущее значение к текущему, что является лучшим способом для этого случая? Если вам нужна дополнительная информация, пожалуйста, дайте мне знать. Я сделаю все возможное

1 Ответ

0 голосов
/ 17 мая 2019
const sumReducer = useCallback((key, data) => (data || []).reduce((previous, current) => {
    return previous + current[constant[key]]
  }, 0), [])

  const commonWallet = useCallback((wallets || []).reduce((previous, current) => {
    if (current.isMain) {
      return previous + current[constant.commonWallet]
    }
    return previous
  }, 0), [wallets])

  const totalBalance = useMemo(() => {
    const balance = sumReducer(constant.balance, wallets)
    const pendingWinnings = sumReducer(constant.pendingWinnings, wallets)
    const bonusBalance = sumReducer(constant.bonusBalance, wallets)

    return [
      {
        property: formatMessage(messages.balance),
        data: balance
      },
      {
        property: formatMessage(messages.pendingWinnings),
        data: pendingWinnings
      },
      {
        property: formatMessage(messages.bonusBalance),
        data: bonusBalance
      },
      {
        property: formatMessage(messages.commonWallet),
        data: commonWallet
      },
      {
        property: formatMessage(messages.totalBonusWallet),
        data: balance + pendingWinnings + bonusBalance
      }
    ]
  }, [wallets])
...