React如何在同一个父组件上显示不同来源的多个组件

React how to display multiple components of different origin on the same parent component

我正在尝试使用 React Js 构建一个仪表板,我想知道如何显示多个组件,但作为小部件,这意味着您需要能够以任何顺序和任何数量添加它们.我的问题是我找不到渲染组件图的方法。

用户可以通过单击按钮将小部件添加到他的仪表板,或者以相同的方式删除它们,所以我不知道将呈现多少个组件

我想做一些事情,例如,当用户点击一个小部件时,它将它添加到仪表板,但我不知道该怎么做。

我尝试将组件存储在地图中,然后使用 forEach 循环通过返回包含组件的 div 来显示它们:

import Weather from '...'
import Currency from '...'
import News from '...'

const map = [Weather, Currency, News]

const runAll = () => {
    map.forEach((fcn) => {
        let runner = fcn
        runner()
    })
}

runAll()

我搜索了很多堆栈和其他论坛问题,但没有找到我需要的

你们知道我可以做些什么来解决这个问题吗?

保留一个状态(数组)来保存用户添加的小部件。为小部件定义常量并将这些常量保存到您的持久性存储中。

const widgets = {天气:1,新闻:2} 将这些值作为 json 保存到数据库中,并在需要时使用用户配置的属性,然后检索此 json 并基于它呈现组件

要保存的示例 JSON 结构 - [{type: 1, prop1: "val"},{type: 2, prop1: "val"}]

const renderWidgets = (array) => {
    const widgets = [];
    array.foreach((widget) => {
        switch(widget) {
            case widgets.weather:
                widgets.push(<Weather ...props/>);
            break;
            .
            .
            .
            etc
        }
    });
    
    return widgets;
}

因此您需要能够轻松渲染 2 件事:

  1. 用户可以单击并在仪表板中添加的小部件列表
  2. 实际的仪表板。列表中所有选定的小部件(具有删除功能)

让我们首先弄清楚我们的 state 应该是什么,它也为组件 1 和组件 2 供电。

  • 对于第一个,我们需要可用小部件的完整列表。由于这是静态的(我们有 3 个可用的小部件),这可以通过声明一次的静态映射(一个简单的 javascript 对象)来表达。
  • 对于第二个,我们需要一组用户选择的小部件。那是动态的部分。我们需要能够设置显示的 initial 小部件,并能够 addremove 小部件从此列表中,允许同一个小部件出现多次。

静态小部件映射

这应该是标识符和 React 小部件组件之间的映射,应该如下所示:

import News from "./News";
import Weather from "./Weather";
import Currency from "./Currency";

const widgetsMapping = {
  news: News,
  weather: Weather,
  currency: Currency
};

小部件状态

这是用户想要在仪表板中使用的小部件标识符数组(来自静态映射的键)。我们还需要 addremove 方法。使用 useState 我们可以这样写:

const [widgets, setWidgets] = useState(["weather", "news"]);

const addWidget = (widget) => {
  setWidgets([...widgets, widget]);
};

const removeWidget = (index) => {
  const updated = [...widgets];
  updated.splice(index, 1);
  setWidgets(updated);
};

渲染

仪表板

然后我们可以通过迭代 widget 状态数组来呈现仪表板:

{widgets.map((widget, index) => {
  const Widget = widgetsMapping[widget];
  return (
    <Widget
      key={`${widget}${index}`}
      removeWidget={() => removeWidget(index)}
    />
  )
})}

removeWidget 道具可用于让小部件在单击某物时自行删除。

可用小部件列表

在这里,我们将遍历静态映射中的所有可用小部件,并使用绑定到它们的 add 功能呈现所有这些小部件。

{Object.keys(widgetsMapping).map((widget) => (
  <button key={widget} onClick={() => addWidget(widget)}>
    {widget}+
  </button>
))}

您可以在 this code sandbox 中找到 完整的工作示例 。对您希望如何添加和删除小部件做出了一些假设,但主要思想保持不变。