React:记账本04---详情页

149 阅读1分钟

详情页

需求:

  • 按日期,按收入支出,分类展示记录

CategorySection

可以复用money页的

展示记录

1. 读取records

  • 使用useRecords hook里的record
const {records} = useRecords();
  • 我们的record里存着
type newRecordItem = {
    tagIds:number[],
    note:string,
    category:"+" | '-',
    amount:number,
}
export type RecordItem = newRecordItem & {
    createdAt:string //ISO 8601
}
  • 但是我们的record里没有存tagName,我需要展示的是name,需要一个getName的方法。新增这个在方法在useTags的hook
    const getName=(id:number)=>{ //根据id找tagName
        const tag = tags.filter(t=>t.id === id)[0]
        return tag ? tag.name : ''
    }

2. 展示所有记录

<Layout>
    <CategoryWrapper>
    <CategorySection value={category} onChange={value=>setCategory(value)}/>
    </CategoryWrapper>
    <div>
        {records.map(r=>{
            return <Item>
                <div className='tags'>
                    {r.tagIds.map(tagId=><span>{getName(tagId)}</span>)}
                </div>
                {r.note && <div className="note">{r.note}</div>}
                <div className="amount">
                    ¥{r.amount}
                </div>
                {/*{day(r.createdAt).format('YYYY年MM月DD日')}*/}
            </Item>
        })}
    </div>
</Layout>

处理日期

  1. 引入一个库dayjs
yarn add dayjs
  1. 使用
import day from 'dayjs'


day(r.createdAt).format('YYYY年MM月DD日')

将记录按支出和收入分类

  1. 计算被选中的records
const selectedRecords =  records.filter(r=>r.category === category)

将记录按日期分组

1. 创建一个hash分日期存储记录

const hash: {[k:string]:RecordItem[]} = {}
  • 格式是: {[k:string]:RecordItem[]}
  • key是string,value是数组(RecordItem类型的数组)
  • 比如
{
    '2021-02-11':[record1,record2,record3],
    '2021-03-11':[record1,record2],
    '2021-02-14':[record1,record3]
}

2. 将selectedRecords按日期分别存入hash

  • 如果当前日期不在hash里(没有这个key),就创建这个key的数组,
  • 然后push进这个key对应的数组
    selectedRecords.forEach(r=>{
        const key = day(r.createdAt).format('YYYY年MM月DD日')
        if(hash[key] === undefined){
            hash[key] = []
        }
        hash[key].push(r)
    })

3. 将产生的hash转为数组

  1. 使用api:Object.entries(将对象变为数组)
  2. 为数组排序
    const arr = Object.entries(hash).sort((a,b)=>{
        if(a[0] === b[0]){
            return 0
        }
        if(a[0] > b[0]){
            return -1
        }
        if(a[0] < b[0]){
            return 1
        }
        return 0
    })
  1. 得到的结果:
    • Rob9J0.png
    • 每一项变为一个数组,
    • 同时数组里日期是第一项,records是第二项(也是一个数组)

4. 展示按日期分类的记录

  1. arr是上一步中得到的按日期分类完的数组,第一项date为日期,第二项records为记录的数组
  2. 如果多标签怎么处理?
  • 比如"衣,食,住,行",标签中间要用逗号隔开
    • 现在:[span,span,span]
    • 想得到[span,',',span,',',span]
  • 使用reduce处理
{r.tagIds.map(tagId=><span key={{tagId}}>{getName(tagId)}</span>)
    .reduce((result,span,index,array)=>
        result.concat(index<array.length -1 ? [span,',']:[span]),[] as ReactNode)
}
  1. 代码
 {arr.map(([date,records])=><div>
    <Header>
        {date}
    </Header>
    <div>
        {records.map(r=>{
            return <Item key={r.createdAt}>
                <div className='tags oneLine'>
                    {r.tagIds.map(tagId=><span key={{tagId}}>{getName(tagId)}</span>)
                        .reduce((result,span,index,array)=>
                            result.concat(index<array.length -1 ? [span,',']:[span]),[] as ReactNode)
                    }
                </div>
                {r.note && <div className="note">{r.note}</div>}
                <div className="amount">
                    ¥{r.amount}
                </div>
            </Item>
        })}
    </div>
</div>)
     
 }