Estoy tratando de crear un tablero con React Js y me gustaría saber cómo podría mostrar varios componentes, pero como widgets, lo que significa que debe poder agregarlos en cualquier orden y en cualquier cantidad. Mi problema es que no puedo encontrar una manera de representar un mapa de componentes.
El usuario puede agregar un widget a su tablero haciendo clic en un botón o eliminarlo de la misma manera, por lo que no sabré cuántos de qué componentes se representarán.
Me gustaría hacer algo como, cuando el usuario hace clic en un widget, lo agrega al tablero, pero no sé cómo hacerlo.
Intenté almacenar componentes en un mapa, luego, con un bucle forEach, los muestro todos al devolver un div que contiene el componente:
import Weather from '...' import Currency from '...' import News from '...' const map = [Weather, Currency, News] const runAll = () => { map.forEach((fcn) => { let runner = fcn runner() }) } runAll()He buscado muchas preguntas de stack y otros foros, sin encontrar lo que necesitaba
¿Tienen alguna idea de lo que podría hacer para solucionar esto?
Mantenga un estado (matriz) que contenga widgets agregados por el usuario. Defina constantes para widgets y guarde estas constantes en su almacenamiento de persistencia.
const widgets = {weather: 1, news: 2} guarde estos valores en la base de datos como json con propiedades configuradas por el usuario si es necesario, y luego recupere este json y represente los componentes en función de él.
ejemplo de estructura JSON para guardar - [{tipo: 1, prop1: "val"},{tipo: 2, prop1: "val"}]
const renderWidgets = (array) => { const widgets = []; array.foreach((widget) => { switch(widget) { case widgets.weather: widgets.push(<Weather ...props/>); break; . . . etc } }); return widgets; }Por lo tanto, debe poder renderizar fácilmente 2 cosas:
Primero averigüemos cuál debería ser nuestro state que también alimente los componentes 1 y 2.
Esto debería ser una asignación entre un identificador y el componente del widget de reacción y debería tener este aspecto:
import News from "./News"; import Weather from "./Weather"; import Currency from "./Currency"; const widgetsMapping = { news: News, weather: Weather, currency: Currency }; Esta es una matriz de identificadores de widgets (las claves del mapeo estático) que el usuario desea en el tablero. También necesitamos agregar y eliminar métodos. Usando useState podemos escribir esto como a continuación:
const [widgets, setWidgets] = useState(["weather", "news"]); const addWidget = (widget) => { setWidgets([...widgets, widget]); }; const removeWidget = (index) => { const updated = [...widgets]; updated.splice(index, 1); setWidgets(updated); }; Luego, podemos representar el tablero al iterar nuestra matriz de estado de widget :
{widgets.map((widget, index) => { const Widget = widgetsMapping[widget]; return ( <Widget key={`${widget}${index}`} removeWidget={() => removeWidget(index)} /> ) })} removeWidget prop se puede usar para permitir que un widget se elimine solo cuando se hace clic en algo.
Aquí iteraremos a través de todos los widgets disponibles de nuestro mapeo estático y los renderizaremos todos con la funcionalidad de agregar vinculada a ellos.
{Object.keys(widgetsMapping).map((widget) => ( <button key={widget} onClick={() => addWidget(widget)}> {widget}+ </button> ))}Puede encontrar un ejemplo de trabajo completo en este entorno limitado de código . Se hicieron algunas suposiciones sobre cómo desea agregar y eliminar widgets, pero la idea principal sigue siendo la misma.