Staram się dynamicznie renderować komponenty na podstawie ich typu.
Na przykład:
var type = "Example";
var ComponentName = type + "Component";
return <ComponentName />;
// Returns <examplecomponent /> instead of <ExampleComponent />
Wypróbowałem rozwiązanie zaproponowane tutaj Dynamiczne nazwy komponentów React / JSX
To dało mi błąd podczas kompilacji (używając browserify dla gulp). Oczekiwano XML, w którym użyłem składni tablicowej.
Mogę rozwiązać ten problem, tworząc metodę dla każdego komponentu:
newExampleComponent() {
return <ExampleComponent />;
}
newComponent(type) {
return this["new" + type + "Component"]();
}
Ale to oznaczałoby nową metodę dla każdego komponentu, który tworzę. Musi istnieć bardziej eleganckie rozwiązanie tego problemu.
Jestem bardzo otwarta na sugestie.
{...this.props}
przydatne do przezroczystego przekazywania rekwizytów do komponentów podrzędnych z rodzica. Na przykładreturn <MyComponent {...this.props} />
Oficjalna dokumentacja dotycząca postępowania w takich sytuacjach jest dostępna tutaj: https://facebook.github.io/react/docs/jsx-in-depth.html#choosing-the-type-at-runtime
Zasadniczo mówi:
Źle:
Poprawny:
źródło
Powinien istnieć kontener, który odwzorowuje nazwy komponentów na wszystkie komponenty, które mają być używane dynamicznie. Klasy komponentów powinny być zarejestrowane w kontenerze, ponieważ w środowisku modułowym nie ma innego miejsca, w którym można by uzyskać do nich dostęp. Klas komponentów nie można zidentyfikować za pomocą nazw bez ich jawnego określenia, ponieważ funkcja
name
jest zminimalizowana w produkcji.Mapa komponentów
Może to być zwykły przedmiot:
Lub na
Map
przykład:Zwykły obiekt jest bardziej odpowiedni, ponieważ korzysta ze skrótu własności.
Moduł beczki
Moduł beczka z wymienionych eksportu może działać jako takiej mapie:
Działa to dobrze z jedną klasą na styl kodu modułu.
Dekorator
Dekoratorów można używać z komponentami klas dla cukru składniowego, ale nadal wymaga to jawnego określenia nazw klas i zarejestrowania ich w mapie:
Dekorator może być używany jako element wyższego rzędu z elementami funkcjonalnymi:
Użycie niestandardowej
displayName
właściwości zamiast losowej również jest korzystne dla debugowania.źródło
Wymyśliłem nowe rozwiązanie. Zwróć uwagę, że używam modułów ES6, więc wymagam klasy. Zamiast tego możesz także zdefiniować nową klasę React.
źródło
default
atrybutu? czyli: require ('./ ExampleComponent'). default?Jeśli Twoje komponenty są globalne, możesz po prostu:
źródło
Components
tablica nie jest zdefiniowana.W przypadku komponentu opakowania prostym rozwiązaniem byłoby użycie
React.createElement
bezpośrednio (przy użyciu ES6).źródło
We wszystkich opcjach z mapami komponentów nie znalazłem najprostszego sposobu na zdefiniowanie mapy przy użyciu krótkiej składni ES6:
źródło
Posiadanie mapy wcale nie wygląda dobrze przy dużej ilości komponentów. Właściwie jestem zaskoczony, że nikt nie zasugerował czegoś takiego:
Ten naprawdę pomógł mi, gdy musiałem wyrenderować całkiem dużą liczbę komponentów załadowanych w postaci tablicy json.
źródło
React.createElement(MyComponent)
bezpośredniego wywołania spowodowała błąd. W szczególności nie chcę, aby rodzic musiał znać wszystkie komponenty do zaimportowania (w mapowaniu) - ponieważ wydaje się to dodatkowym krokiem. Zamiast tego użyłemconst MyComponent = require("path/to/component/" + "ComponentNameString").default; return <MyComponent />
.Podejrzewamy, że chcemy uzyskać dostęp do różnych widoków z dynamicznym ładowaniem komponentów. Poniższy kod przedstawia działający przykład, jak to zrobić, używając ciągu przeanalizowanego z ciągu wyszukiwania adresu URL.
Załóżmy, że chcemy uzyskać dostęp do strony „snozberrys” z dwoma unikalnymi widokami przy użyciu następujących ścieżek URL:
i
definiujemy kontroler naszego widoku w ten sposób:
źródło
Załóżmy, że mamy a
flag
, nie różni się odstate
orprops
:Z flagą
Compo
wypełnij jedną zComponentOne
lub,ComponentTwo
a następnieCompo
może działać jak komponent reagujący.źródło
Użyłem nieco innego podejścia, ponieważ zawsze znamy nasze rzeczywiste komponenty, więc pomyślałem, że zastosuję obudowę przełącznika. Również całkowita liczba komponentów w moim przypadku wynosiła około 7-8.
źródło
Edycja: inne odpowiedzi są lepsze, zobacz komentarze.
W ten sposób rozwiązałem ten sam problem:
źródło
React.createElement
zostanie wywołany dla każdego składnika w obiekcie wyszukiwania, nawet jeśli tylko jeden z nich jest renderowany na raz. Co gorsza, umieszczając obiekt odnośnika wrender
metodzie komponentu rodzica, zrobi to ponownie za każdym razem, gdy element nadrzędny jest renderowany. Najlepsze odpowiedzi to znacznie lepszy sposób na osiągnięcie tego samego.