React Native ist ein plattformübergreifendes Framework zur Entwicklung mobiler Anwendungen, das im April 2015 von Facebook als Open Source veröffentlicht wurde. In nur ein bis zwei Jahren haben viele Unternehmen dieses Framework unterstützt und übernommen, um die mobilen Anwendungen ihres Unternehmens zu erstellen. Projektrahmen und Projektstruktur1. Im Projekt verwendeter Technologie-StackReact Native, React Hook, Typescript, Immer, Tslint, Jest usw. Sie sind alle recht verbreitet, deshalb werde ich sie nicht im Detail vorstellen. 2. Die Datenverarbeitung verwendet useContext+useReducer im React-HookDie Idee entspricht Redux, es ist relativ einfach zu verwenden und für weniger komplexe Geschäftsszenarien geeignet. const HomeContext = createContext<IContext>({ Status: Standardstatus, Versand: () => {} }); const ContextProvider = ({ urlQuery, pageCode }: IProps) => { const initState = getInitState(urlQuery, pageCode); const [Status, Versand]: [IHomeState, IDispatch] = useReducer(homeReducer, initState); zurückkehren ( <HomeContext.Provider-Wert={{ Status, Dispatch }}> <HomeContainer /> </HomeContext.Provider> ); }; const HomeContainer = () => { const { Versand, Status } = useContext(HomeContext); ... 3. Die Projektstruktur ist wie folgt|-Seite1 |-handler // Reine Funktion zur Verarbeitungslogik, muss durch UT abgedeckt werden|-container // Daten, Verhalten und Komponenten integrieren|-component // Reine UI-Komponente, zeigt Inhalt und Benutzerinteraktion an, verarbeitet keine Geschäftslogik|-store // Die Datenstruktur darf 3 Ebenen nicht überschreiten und die Ebene kann durch externe Referenzen und redundante Felder reduziert werden|-reducer // Immer verwenden, um neue Daten zurückzugeben (unveränderliche Daten) |-... |-Seite2 |-... Vorgaben im Projekt1. SeiteDas gesamte Projekt ist eine mehrseitige Anwendung und die grundlegendste Aufteilungseinheit ist die Seite. Jede Seite hat einen entsprechenden Store, nicht das gesamte Projekt verwendet einen Store. Die Gründe dafür sind folgende:
Externe Vorgänge auf jeder Seite werden in der Seitenkomponente definiert
Die Hauptfunktion der SeitenkomponenteBasierend auf einem eigenen Business-Modul werden alle abstrahierbaren externen Abhängigkeiten und externen Interaktionen im Code dieser Komponente konzentriert. Für Entwickler ist es praktisch, beim Schreiben von Logik und bei der Fehlersuche zwischen Seiten bestimmte Codes entsprechend bestimmter Seiten + Datenquellen genau zu lokalisieren. 2. ReduzierstückIn früheren Projekten konnten Reducer einige Datenverarbeitungen, Benutzerverhalten, Protokollpunkte, Seitensprünge und andere Codelogik beinhalten. Denn beim Schreiben des Codes stellen Entwickler fest, dass der Reducer der Endpunkt einer bestimmten Verarbeitungslogik ist (nach dem Aktualisieren des Status ist das Ereignis beendet), was sich für diese Aufgaben sehr gut eignet. Mit der Wartung des Projekts und der Iteration der Anforderungen nimmt die Größe des Reduzierers weiter zu. Aufgrund der fehlenden Organisation und der riesigen Menge an Code wäre es schwierig, den Code anzupassen. Es ist vorstellbar, wie mühselig es für Sie wäre, ein solches Projekt aufrechtzuerhalten. Zu diesem Zweck wurden einige Subtraktionen am Code im Reducer vorgenommen:
Die Hauptfunktion des ReduzierersFassen Sie alle Szenarien der Betriebsdaten auf der Seite in aufzählbarer Form zusammen. Zusätzlich zu seinen eigenen Funktionen, die für das React-Framework geeignet sind, ist es mit bestimmten Attributen zum Lesen der Geschäftslogik ausgestattet, sodass die gesamte Datenverarbeitungslogik auf der Seite grob gelesen werden kann, ohne auf UI-Komponenten angewiesen zu sein. // Vermeiden Sie doppeltes Versenden und das Definieren zu vieler Einzelfeld-Aktualisierungsfälle // Nach der Integration dieser Logik wird sie mit dem Verhalten auf der Seite verknüpft, was zum Verständnis und Lesen des Falls beiträgt. EFHListAction.updateSpecifyQueryMessage: returniere produzieren(Zustand, (Entwurf: IFHListState) => { draft.specifyQueryMessage = Nutzlast als Zeichenfolge; Entwurf.showSpecifyQueryMessage = true; }); Fall EFHlistAction.updateShowSpecifyQueryMessage: returniere produzieren(Zustand, (Entwurf: IFHListState) => { draft.showSpecifyQueryMessage = Nutzlast als Boolescher Wert; }); 3. HandlerHier führen wir zunächst das Konzept einer reinen Funktion ein: Eine Funktion heißt reine Funktion, wenn ihr Rückgabewert nur von ihren Parametern abhängt und sie bei der Ausführung keine Nebenwirkungen hat. Abstrahieren Sie so viel Logik wie möglich in reine Funktionen und packen Sie diese in Handler:
Die Hauptfunktion des HandlersVerantwortlich für die logische Verarbeitung in Szenarien wie Datenquelle zum Speichern, Container zur Komponente, Versand zum Reduzierer usw. Als Speicherort für logische Verarbeitungsfunktionen in verschiedenen Szenarien ist die gesamte Datei nicht an der Zuordnungsbeziehung im Seitenprozess beteiligt. Jede Funktion kann wiederverwendet werden, solange sie die Verwendungsszenarien ihrer Eingabe und Ausgabe erfüllt, und wird hauptsächlich in Containerdateien verwendet. Exportfunktion getFilterAndSortResult( Flugliste: IFlightInfo[], filterList: IFilterItem[], filterShare: Boolesch, filterOnlyDirect: Boolesch, Sortiertyp: EFlightSortType ) { wenn (!isValidArray(flugliste)) { zurückkehren []; } const sortFn = getSortFn(sortType); const Ergebnis = Flugliste.Filter(v => doFilter(v, Filterliste, Filteranteil, 1, FilternurDirekt)).Sort(SortFn); Ergebnis zurückgeben; } beschreiben(getFilterAndSortResult.name, () => { test('getFilterAndSortResult', () => { Erwarte (getFilterAndSortResult (Flugliste, Filterliste, falsch, EFlightSortType.PriceAsc)). gleich (FilterSortResult); }); }); 4. BehälterWie aus dem obigen Projektstrukturdiagramm ersichtlich ist, verfügt jede Seite über einen Basiscontainer als Zentrum der Datenverarbeitung. Unter diesem Basiscontainer wird jeder Untercontainer entsprechend unterschiedlicher Module definiert:
Die Hauptfunktion von ContainerIm gesamten Projekt sollten die Konvergenzpunkte verschiedener Daten, Benutzeroberflächen und Benutzerverhalten so weit wie möglich von den entsprechenden Modulen getrennt werden, um ein übermäßiges Codevolumen und Wartungsschwierigkeiten zu vermeiden. Die Definition des Containers sollte durch die auf der Seite angezeigten Module abstrahiert werden. Beispielsweise Head-Container, Inhaltscontainer, Footer-Container und andere gängige Unterteilungsmethoden. Einige relativ unabhängige Module auf einigen Seiten sollten auch ihre entsprechenden Container erstellen, um die zugehörige Logik zu aggregieren, z. B. das Modul zur Couponvergabe, das Modul zum Benutzerfeedback usw. Achten Sie besonders auf die Verhaltensfunktion
Praktisch zum Lesen des Codes: Die schwebende Anzeigelogik von Modul A und die Reihenfolge, in der Module generiert werden, wenn Modul B verwendet wird, müssen zuerst Modul A und dann Modul B die Methode von A verwenden.
const OWFlightListContainer = () => { // Daten über Context abrufen const { state, dispatch } = useContext(OWFlightListContext); ... // Countdown für Timeout beim ersten Laden useOnce(overTimeCountDown); ... // Benutzer klickt auf Sortieren const onPressSort = (lastSortType: EFlightSortType, isTimeSort: boolean) => { // Referenziert die Funktion getNextSortType im Handler const sortType = getNextSortType(lastSortType, isTimeSort); Dispatch ({Typ: EOWFlightListAction.updateSortType, Nutzlast: Sortiertyp}); // Punktvergrabener Vorgang logSort(state, sortType); }; // Rendern der Anzeigekomponente return <.../>; } Zusammenfassung Von einfach zu codieren bis einfach zu lesen
Es ist relativ einfach, die Spezifikation zu definieren. Um ein Projekt erfolgreich aufrechtzuerhalten, kommt es eher darauf an, dass die Teammitglieder beharrlich an der Prämisse festhalten, einen Konsens zu erreichen. Teilen Sie einige praktische FunktionenWert basierend auf dem Objektpfad abrufen /** * Holen Sie sich den Wert basierend auf dem Objektpfad* @param target {a: { b: { c: [1] } } } * @param Pfad 'abc0' */ Exportfunktion getVal(Ziel: beliebig, Pfad: Zeichenfolge, Standardwert: beliebig = undefiniert) { lass ret = Ziel; let-Schlüssel: Zeichenfolge | undefiniert = ''; const PfadList = Pfad.split('.'); Tun { Schlüssel = Pfadliste.Shift(); wenn (ret && Schlüssel !== undefiniert && Typ von ret === 'Objekt' && Schlüssel in ret) { ret = ret[Schlüssel]; } anders { ret = undefiniert; } } während (Pfadliste.Länge && ret !== undefiniert); return ret === undefiniert || ret === null? Standardwert: ret; } //DEMO const errorCode = getVal(Ergebnis, 'rstlist.0.type', 0); Lesen Sie gemäß den Konfigurationsinformationen // Bei der Anbindung an die Außenwelt werden oft feste Strukturen und skalierbare Datenlisten definiert. // Um sich an solche Verträge anzupassen und eine bessere Lesbarkeit und Wartung zu ermöglichen, werden folgende Funktionen zusammengefasst. export const GLOBAL_NOTE_CONFIG = { 2: 'Rückerstattung', 3: 'Sortierungstyp', 4: "Featureschalter" }; /** * Holen Sie sich gemäß der Konfiguration den Wert in attrList und geben Sie die Daten des JSON-Objekttyps zurück * @private * @Mitglied von DetailService */ Exportfunktion getNoteValue<T>( noteList: Array<T> | nicht definiert | null, Konfiguration: { [_: Zeichenfolge]: Zeichenfolge }, Schlüsselname: Zeichenfolge = "Typ" ) { const ret: { [_: Zeichenfolge]: T | Array<T> } = {}; wenn (!isValidArray(noteList!)) { Rückkehr ret; } //@ts-ignorieren noteList.forEach((Hinweis: beliebig) => { const typeStr: string = (('' + note[keyName]) als unbekannt) als string; if (!(typeStr in config)) { zurückkehren; } if (Hinweis === undefiniert || Hinweis === null) { zurückkehren; } const key = konfiguration[typeStr]; // Wenn mehrere Werte vorhanden sind, zum Array-Typ wechseln if (ret[key] === undefined) { ret[Schlüssel] = Notiz; } sonst wenn (Array.isArray(ret[key])) { (ret[Taste] als T[]).push(Hinweis); } anders { const first = ret[Schlüssel]; ret[Schlüssel] = [erste, Notiz]; } }); Rückkehr ret; } //DEMO // Anwendbar auf die Wertelogik einiger extern definierter erweiterbarer Notizknotenlisten const { sortType, featureSwitch } = getNoteValue(list, GLOBAL_NOTE_CONFIG, 'ntype'); Sortieren von Arrays mit mehreren Bedingungen /** * Holt die zum Sortieren verwendete Sortierfunktion * @param fn Vergleichsfunktion für Elemente gleichen Typs, true bedeutet Sortierpriorität */ Exportfunktion getSort<T>(fn: (a: T, b: T) => boolean): (a: T, b: T) => 1 | -1 | 0 { Rückgabewert (a: T, b: T): 1 | -1 | 0 => { sei ret = 0; wenn (fn.call(null, a, b)) { ret = -1; } sonst wenn (fn.call(null, b, a)) { ret = 1; } gib ret als 0 zurück; }; } /** * Mehrfachsortierung */ Exportfunktion getMultipleSort<T>(arr: Array<(a: T, b: T) => 1 | -1 | 0>) { Rückgabewert (a: T, b: T) => { lass tmp; sei i = 0; Tun { tmp = arr[i++](a, b); } während (tmp === 0 und i < arr.length); temporär zurückgeben; }; } //DEMO const ageSort = getSort(Funktion(a, b) { returniere a.Alter < b.Alter; }); const nameSort = getSort(Funktion(a, b) { gibt a.name < b.name zurück; }); const sexSort = getSort(Funktion(a, b) { gebe a.Geschlecht und !b.Geschlecht zurück; }); //Die Reihenfolge der Beurteilungsbedingungen kann angepasst werden const arr = [nameSort, ageSort, sexSort]; const ret = data.sort(getMultipleSort(arr)); Oben sind einige Details meiner Erfahrungen beim Erstellen des React Native-Projektframeworks aufgeführt. Weitere Informationen zum Erstellen des React Native-Projektframeworks finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM! Das könnte Sie auch interessieren:
|
<<: So erstellen Sie einen neuen Benutzer in CentOS und aktivieren die Schlüsselanmeldung
>>: Beispiel für die MySQL-Volltext-Fuzzy-Suche nach der Methode MATCH AGAINST
1. Den aktuellen Hostnamen anzeigen [root@fangjia...
In diesem Artikel wird der spezifische JavaScript...
Verwenden Sie Vue, um einfach einen Click-Flip-Ef...
Allgemeine utf8mb4-Sortierregeln in MySQL sind: u...
Inhaltsverzeichnis Vorwort 1. Gründe: 2. Lösungsi...
Inhaltsverzeichnis 1. Werte innerhalb von Schleif...
Kobold-Kuh herunterladen CSS-Fussel herunterladen...
Erstellen Sie Ihre erste Webseite in einer Minute...
Dieser Artikel beschreibt, wie man die PHP-Curl-E...
Nginx ist mittlerweile einer der beliebtesten Loa...
CSS steuert den Druckstil von Webseiten : Verwende...
Inhaltsverzeichnis 1. Clevere Verwendung von Indi...
Die CSS-Animation des rotierenden Flip-Effekts, d...
1. Vergleichen Sie den alten virtuellen DOM mit d...
<br />Verwandte Artikel: 9 praktische Vorsch...