Así que tengo dos componentes: Tag y TagGroup. Cuando el componente de etiqueta se usa solo, quiero que ese componente use la etiqueta <div>
y cuando la etiqueta está envuelta dentro de TagGroup, lo que significa que se está usando más de 1 etiqueta, entonces quiero que use la etiqueta <li>
. Con mi diseño actual, utilicé el contexto para pasar prop groupUpTags
al componente Tag. Cuando groupUpTags
es verdadero, el componente Etiqueta usará la etiqueta <li>
, si es falso, se usará <div>
. Actualmente, ni siquiera funciona correctamente, ya que si envuelvo el componente Tag en TagGroup o no, siempre se usa la etiqueta <li>
. Mi pregunta es, ¿hay alguna manera de hacer que el componente Tag represente la etiqueta <li>
cuando se envuelve dentro de TagGroup sin usar ningún accesorio y represente la etiqueta <div>
cuando se usa solo? Mi diseño actual se ve demasiado desordenado. https://codesandbox.io/s/tag-group-s07oyh?file=/src/App.tsx
Aplicación.tsx
import "./styles.css"; import React from "react"; import { TagGroupContextInterface, TagGroupContext } from "./TagGroupContext"; export interface TagGroupInterface extends TagGroupContextInterface { children: React.ReactNode; } const Tag = () => { const context = React.useContext(TagGroupContext); return context.groupUpTags ? ( <li className="tag">Tag</li> ) : ( <div className="tag">Tag</div> ); }; const TagGroup = ({ groupUpTags = true, children }: TagGroupInterface) => { const context = React.useMemo( () => ({ groupUpTags }), [groupUpTags] ); return ( <TagGroupContext.Provider value={context}> <div> <ul>{React.Children.map(children, (child) => child)}</ul> </div> </TagGroupContext.Provider> ); }; export default function App() { return ( <div className="App"> <TagGroup> <Tag /> <Tag /> <Tag /> </TagGroup> </div> ); }
TagGroupContext.tsx
import React from "react"; export interface TagGroupContextInterface { groupUpTags?: boolean; } const defaultTagGroupContext: TagGroupContextInterface = { groupUpTags: true }; export const TagGroupContext = React.createContext<TagGroupContextInterface>( defaultTagGroupContext );
Un componente de etiqueta probablemente siempre deba devolver una etiqueta simple en un div o un lapso, lo que sea que necesite para que funcione la etiqueta independiente.
Luego agregaría el li dentro del componente de la lista, ya que ese es el momento en que necesita el li. cuando codifica una etiqueta, no debe saber acerca de los padres.
Probablemente algo como esto en su grupo de etiquetas
{Children.map(children, (child, i) => { <li key={i}>{child}</li>; })}
nota: no use "i" como clave, no es confiable. Utilice un uid de la propia etiqueta.