如何根据 GROQ 查询字段的值有条件地呈现选项卡?

How can I conditionally render tabs depending on the value of a field of a GROQ query?

我有一个 GROQ 查询,其结果是一个文档数组,其中一个字段“fieldName”可以包含“a”、“b”或“c”。如果数组包含任何值为“a”的值,那么我想在 <TabList> 中为其显示 Chakra-UI <Tab> 以及 <TabPanel><TabPanels>。如果有 none 个值为“a”,则不显示制表符,并对条件“b”和“c”重复此操作。

// GROQ query

*[slug.current == $slug]{
    array[]->
}
// GROQ query json response

"result": [
    0:
    "array": [
        0: {...}
        1: {
            "_id": "1"
            "fieldName": "a"
        }
        2: {
            "_id": "2"
            "fieldName": "c"
        }
        3: {...}
        4: {...}
        5: {...}
        ]
    }
]

// This example would return tabs and panels for only a and c

我知道如何在下面的示例中有条件地循环遍历项目,但这对 Tab 项目没有帮助,因为循环遍历这些项目会给我重复的标签。

<Tabs>
  <TabList>
    <Tab>A</Tab> // Conditionally render this only if any array items' "fieldName" contains value "a"

    ...

  </TabList>
  <TabPanels>
    <TabPanel>
      {array &&
        array.fieldName.map((panel) => (
          <>{panel.fieldName == "a" ? <>{panel.fieldName}</> : null}</>
        ))}
    </TabPanel>

    ...

  </TabPanels>
</Tabs>

由于 Chakra-UI 选项卡的结构,我对如何执行此操作感到困惑,并希望得到任何帮助。一定有比我正在尝试的方法更好的方法吗?

您可以创建一个对象并使用它来检查是否显示特定的选项卡和选项卡面板

import React from 'react';
import {
  ChakraProvider,
  Tabs,
  TabList,
  TabPanels,
  Tab,
  TabPanel,
} from '@chakra-ui/react';
import './style.css';

const arr = [
  {
    _id: '1',
    fieldName: 'a',
  },
  {
    _id: '2',
  },
  {
    _id: '3',
    fieldName: 'c',
  },
  {
    _id: '4',
    fieldName: 'a',
  },
  {
    _id: '5',
    fieldName: 'c',
  },
  {
    _id: '6',
    fieldName: 'e',
  },
  {
    _id: '7',
  },
  {
    _id: '8',
    fieldName: 'c',
  },
  {
    _id: '9',
    fieldName: 'a',
  },
];

function process(arr) {
  const tabs = {};
  arr.forEach((item, idx) => {
    if (item.fieldName && !tabs[item.fieldName]) {
      tabs[item.fieldName] = idx;
    }
  });
  return tabs;
}

export default function App() {
  const tabs = process(arr);
  return (
    <ChakraProvider>
      <Tabs>
        <TabList>
          {tabs['a'] && <Tab>A</Tab>}
          {tabs['b'] && <Tab>B</Tab>}
          {tabs['c'] && <Tab>C</Tab>}
          {tabs['d'] && <Tab>D</Tab>}
          {tabs['e'] && <Tab>E</Tab>}
        </TabList>

        <TabPanels>
          {tabs['a'] && (
            <TabPanel>
              <p>A</p>
            </TabPanel>
          )}
          {tabs['b'] && (
            <TabPanel>
              <p>B</p>
            </TabPanel>
          )}
          {tabs['c'] && (
            <TabPanel>
              <p>C</p>
            </TabPanel>
          )}
          {tabs['d'] && (
            <TabPanel>
              <p>D</p>
            </TabPanel>
          )}
          {tabs['e'] && (
            <TabPanel>
              <p>E</p>
            </TabPanel>
          )}
        </TabPanels>
      </Tabs>
    </ChakraProvider>
  );
}

Working Example