代码之家  ›  专栏  ›  技术社区  ›  Magician

React中变量更改时关闭和重新打开标记的干净方式

  •  1
  • Magician  · 技术社区  · 7 年前

    我有这样一个数组:

    [
        {
            group: "A",
            id: "1",
            name: "Mike"
        },
        {
            group: "A",
            id: "6",
            name: "Sherley"
        },
        {
            group: "B",
            id: "3",
            name: "Charlie"
        },
        {
            group: "C",
            id: "2",
            name: "Dave"
        }
    ]
    

    我想根据数组的组对数组进行分组。数组已按组和名称排序。所以,我做了这样的东西:

    let lastgroup = c[0].group
    return <Group title={lastgroup}>
        {c.map(x => {
            if (lastgroup == x.group) {
                return <a href={"#" + x.id}>{x.name}</a>
            } else {
                lastgroup = x.group
                return </Group><Group title={lastgroup}><a href={"#" + x.id}>{x.name}</a> //-> What should I put here for something like this?
            }
        })}
    </Group>
    

    现在,上面的解决方案显然不起作用,而且是不干净的。如何关闭和重新打开标签?还是有更干净的方法?

    非常感谢。

    2 回复  |  直到 7 年前
        1
  •  0
  •   Dacre Denny    7 年前

    为了清理实现,我建议使用一个中间过程,通过 Array#reduce() Object#entries() 在简化的结果中,使用 <Group /> 标签。

    reduce步骤通过 group

    第二步是映射“简化对象”的条目。这允许您包装 <Group/> 在前面的reduce步骤中为每个组收集的组项周围的标记,而不需要 lastgroup

    // Component state / data
    
    var data = [
        {
            group: "A",
            id: "1",
            name: "Mike"
        },
        {
            group: "A",
            id: "6",
            name: "Sherley"
        },
        {
            group: "B",
            id: "3",
            name: "Charlie"
        },
        {
            group: "C",
            id: "2",
            name: "Dave"
        }
    ]
    
    // Component render method
    
    render() {
    
      return Object.entries(data
      .reduce((grouping, item) => {
    
        // Insert items for group if not present
        if( !grouping[ item.group ] ) {
            grouping[ item.group ] = [];
        }
    
        var groupItems = grouping[ item.group ];
    
        // Create each group item, as we build up the items for this group
        groupItems.push(<a href={"#" + item.id}>{item.name}</a>);
    
        return grouping;
    
      }, {}))
      .map((entry) => {
    
        // entry[0] is the group key, entry[0] is the group value (item array)
        const group = entry[0];
        const items = entry[1];
    
        // Wrap items of each group with <Group/> tags
        return <Group title={group}>{ items }</Group>
      })
    
    }
        2
  •  0
  •   Rico Chen    7 年前

    步骤1,按属性对条目分组 group . 看见 How to group an array of objects by key

    const groups = data.reduce((reducer, current) => {
        reducer[current.group] = reducer[current.group] || []
        reducer[current.group].push(current)
        return reducer
    }, {})
    /* 
       console.log(groups)
       should give you
       { A:
           [ { group: 'A', id: '1', name: 'Mike' },
             { group: 'A', id: '6', name: 'Sherley' } 
         ],
         B: 
           [ { group: 'B', id: '3', name: 'Charlie' } ],
         C: 
           [ { group: 'C', id: '2', name: 'Dave' } ] 
        }
    */
    

    第2步,渲染组

    const keys = Object.keys(groups)
    return (<div>
        {keys.map(key => {
            const currentGroup = groups[key]
            // now render entries inside each group
            return (<Group key={key} title={key}>
                {currentGroup.map(entry => {
                    return <a key={entry.id} href={`#${entry.id}`}>{entry.name}</a>
                })}
            </Group>)
        })}
    </div>)