【问题标题】:create a new array, removing duplicates and setting state with React创建一个新数组,删除重复项并使用 React 设置状态
【发布时间】:2021-12-27 16:24:57
【问题描述】:

我有一个 MenuOptions 组件,我将选项道具传递给它。选项是一大堆对象。每个对象都有一个嵌套数组,称为“服务”,服务内部是一个带有键“serviceType”的对象,这是我想要的唯一值。我想获取所有这些值,将它们推入一个新数组并删除任何重复项(如果有),然后映射该新数组并在“选项”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 似乎持有我想要的东西,但现在我想将它设置为一个全局状态。尝试这样的事情是行不通的。数组似乎仍然设置为 null

    const [array, setArray] = useState(null)

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

有什么解决办法吗?谢谢

【问题讨论】:

  • 我已经发布了一个解决方案,如果是你想要的,请检查一下
  • “这不起作用”是什么意思?
  • 你能显示更多上下文吗? MenuOptions 的定义是什么样的?

标签: javascript arrays reactjs use-effect use-state


【解决方案1】:

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

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;
}

【讨论】:

  • 为什么不简单,fn = (a) =&gt; [...new Set(a)]
  • 从外观上看,他们有一个有效的实现,而是询问它是如何不渲染的
  • 哦,是的,你是对的,这个问题需要更多的上下文
【解决方案2】:

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());
}, []);

【讨论】:

    【解决方案3】:

    如果您想要独特的选项,只需将选项传入并设置为您处理数据后的状态。

    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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-02-22
      • 2021-12-08
      • 1970-01-01
      • 2017-08-17
      • 1970-01-01
      • 1970-01-01
      • 2020-06-22
      相关资源
      最近更新 更多