如何实现基于嵌套数组的UI?

How to implement UI based on nested array?

我有一个带有一些动态值的数组,它将包含数组的数组,并且根据内部数组长度需要显示 OR 文本。

示例:

JSON数据:

const renderArr = [
  {
    label: "Abc",
    value: []
  },
  {
    label: "XyZ",
    value: ["Test", "Exam"]
  },
  {
    label: "Dex",
    value: []
  },
  {
    label: "Mno",
    value: ["Momo", "Pizza"]
  },
  {
    label: "Pqr",
    value: []
  }
];

根据上面的结构,在renderArr[1].value and renderArr[3].value中有值。所以我需要在 UI

中显示这些之间的“或”文本

预期逻辑:

I want to show OR condition based on below condition

let currentValue = renderArr[index].value.length > 0 then

If nextValue = renderArr[index+1].value.length > 0 then show OR condition, NOTE: it'll check till it not found the value.length > 0 for every index

以下是我的逻辑,不正常。

我的逻辑:

shouldShowNextOr = (value, rootIndex) => {
    let shouldShow = false;
    let f = renderArr;
    if (rootIndex < 4) {
      switch (rootIndex) {
        case 0:
          shouldShow =
            f[1].value.length > 0 ||
            f[2].value.length > 0 ||
            f[3].value.length > 0 ||
            f[4].value.length > 0
              ? true
              : false;
          break;
        case 1:
          shouldShow =
            f[2].value.length > 0 ||
            f[3].value.length > 0 ||
            f[4].value.length > 0
              ? true
              : false;
          break;
        case 2:
          shouldShow =
            f[3].value.length > 0 || f[4].value.length > 0 ? true : false;
          break;
        case 3:
          shouldShow = f[4].value.length > 0 ? true : false;
          break;
        default:
          shouldShow = false;
      }
    }

    return shouldShow;
  };

这里是online codesandbox

当前输出

预期输出

过滤 renderArray(在我的示例中为 data),并删除所有 value 数组为空的项目。渲染过滤后的数组,如果某个项目不是最后一个 (i < filteredData.length - 1),您可以在它之后渲染“OR”:

const { useMemo } = React;

const App = ({ data }) => {
  const filteredData = useMemo(() => data.filter(o => o.value.length), [data]);

  return (
    <div className="App">
    {filteredData.map((o, i) => (
      <React.Fragment key={o.label}>
        <div>
          <span>{o.label}</span> ={" "}
          {o.value.join(" and ")}
        </div>
        {i < filteredData.length - 1 &&
          <span>OR<br /></span>
        }
      </React.Fragment>
    ))}
    </div>
  );
};
 
 const renderArr = [{"label":"Abc","value":[]},{"label":"XyZ","value":["Test","Exam"]},{"label":"Dex","value":[]},{"label":"Mno","value":["Momo","Pizza"]},{"label":"Pqr","value":[]}];

ReactDOM.render(
  <App data={renderArr} />,
  root
)
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

<div id="root"></div>

如果需要原始索引,在过滤前使用Array.map()包含在对象中:

const { useMemo } = React;

const App = ({ data }) => {
  const filteredData = useMemo(() => 
    data
      .map((o, index) => ({ ...o, index }))
      .filter(o => o.value.length)
  , [data]);

  return (
    <div className="App">
    {filteredData.map((o, i) => (
      <React.Fragment key={o.label}>
        <div>
          <span>{o.label} - {o.index}</span> ={" "}
          {o.value.join(" and ")}
        </div>
        {i < filteredData.length - 1 &&
          <span>OR<br /></span>
        }
      </React.Fragment>
    ))}
    </div>
  );
};
 
 const renderArr = [{"label":"Abc","value":[]},{"label":"XyZ","value":["Test","Exam"]},{"label":"Dex","value":[]},{"label":"Mno","value":["Momo","Pizza"]},{"label":"Pqr","value":[]}];

ReactDOM.render(
  <App data={renderArr} />,
  root
)
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

<div id="root"></div>

另一种方法是:将具有 valuerenderArray 的所有索引值存储在另一个数组中(在我的示例中为 arr)。检查 rootIndex 是否是 arr.

的一部分

这是code

arrIndex = [];

shouldShowNextOr = (value, rootIndex) => {
let shouldShow = false;
let f = renderArr;
let arr = this.arrIndex;
//storing all the indices which has value
if (arr.length === 0) {
  f.forEach(function (a, index) {
    if (a.value.length > 0) arr.push(index);
  });
}
//check if root index exists
if (arr.includes(rootIndex) && arr.length > 1) {
  //skip the last element in the array.
  if (rootIndex === arr[arr.length - 1]) {
    shouldShow = false;
  } else {
    shouldShow = true;
  }
}

return shouldShow;

};

输入:

const renderArr = [
  {
    label: "Abc",
    value: []
  },
  {
    label: "XyZ",
    value: ["Yes", "No"]
  },
  {
    label: "Dex",
    value: []
  },
  {
    label: "Mno",
    value: ["Hi","Hello"]
  },
  {
    label: "Pqr",
    value: ["Yes", "No"]
  }
];

Output:



XyZ = Yes and No
OR
Mno = Hi and Hello
OR
Pqr = Yes and No