创建一个新数组,删除重复项并使用 React 设置状态

create a new array, removing duplicates and setting state with React

我有一个 MenuOptions 组件,我向其传递了一个选项道具。选项是一大堆对象。每个对象都有一个名为 'services' 的嵌套数组,服务内部是一个带有键 'serviceType' 的对象,这是我想要的唯一值。我想获取所有这些值,将它们推入一个新数组并删除所有重复项(如果有),然后映射到该新数组并将每个项目显示在 'option' html 标记中。

这是我的 createArray 函数:

    const createNewArray = () => {
        let optionsArr = []
        let uniqueArr;

        options.map((option) => {
            option.services.map((service) => optionsArr.push(service.serviceType))
        })
        uniqueArr = [...new Set(optionsArr)];
        return uniqueArr;
    }

uniqArr 似乎持有我想要的东西,但现在我想将其设置为一个全局状态。尝试这样的事情是行不通的。 array 似乎仍被设置为 null

    const [array, setArray] = useState(null)

   useEffect(() => {
      setArray(createNewArray())
   }, [])

有什么解决办法吗?谢谢

根据您的描述,这是您的数据吗?

const options = [{
  services: [
    {
      serviceType: 'serviceType',
    }
  ],
},{
  services: [
    {
      serviceType: 'serviceType',
    }
  ],
},{
  services: [
    {
      serviceType: 'serviceType',
    }
  ],
},
{
  services: [
    {
      serviceType: 'serviceType',
    }
  ],
}]

这是解决方案

const uniq = (a) => [...new Set(a)];

const createNewArray = (array) => {
  const c = [...array]
  const newArray = []
  for (let i = 0; i < c.length; i++) {
    const e = c[i];
    for (let ii = 0; ii < e.length; ii++) {
      const ee = e[ii].serviceType;
      newArray.push(ee);
    }
  }
  const toReturn = uniq(newArray)
  return toReturn;
}

1) 您应该将 array 状态初始值添加为空数组:

const [array, setArray] = useState([]);

现场演示

2) 您可以将新数组的创建简化为:

const createNewArray = () => [
  ...new Set(options.flatMap((o) => o.services.map((obj) => obj.serviceType)))
];

3)useEffect 中的 array 状态设置为:

useEffect(() => {
  setArray(createNewArray());
}, []);

如果你想要独特的选项,只需将选项传入并将它们设置为按摩数据后的状态。

const { useEffect, useMemo, useState } = React;

const unique = (arr) => [...new Set(arr)];

const uniqueOptions = (options) =>
  unique(options.flatMap(({ services }) =>
    services.map(({ serviceType }) => serviceType)));

const data = {
  options: [
    { services: [{ serviceType: "Home"  } , { serviceType: "About" }] },
    { services: [{ serviceType: "About" } , { serviceType: "Help"  }] },
    { services: [{ serviceType: "Help"  } , { serviceType: "Home"  }] },
  ],
};

const MenuOptions = (props) => {
  const { options } = props;

  const [opts, setOpts] = useState([]);

  useEffect(() => setOpts(uniqueOptions(options)), [options]);

  return useMemo(
    () => (
      <select>
        {opts.map((opt) => (
          <option key={opt} value={opt}>
            {opt}
          </option>
        ))}
      </select>
    ),
    [opts]
  );
};

const App = ({ title }) =>
  useMemo(
    () => (
      <div>
        <h1>Services</h1>
        <form>
          <MenuOptions options={data.options} />
        </form>
      </div>
    ),
    []
  );

ReactDOM.render(<App />, document.getElementById("react-app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react-app"></div>