更好的使用React钩子减少的方法

时间:2019-05-17 15:26:09

标签: javascript reactjs immutable.js react-hooks

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 :(得分:0)

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])