2015-10-29 8 views
9

Ich habe angefangen Redux mit React zu verwenden, und ich liebe es absolut. Das Problem, das ich derzeit habe, ist, dass ich neben dem Status auch mehr Informationen habe, die ich in meiner Anwendung speichern/verwenden muss.Verwenden von Redux mit Modellen

In diesem speziellen Fall habe ich ein Modell mit Zustand, der aus einer API abgerufen wird. Dieses Modell hat auch einige Informationen über sich selbst, z.B. wie Sie eine Eigenschaft auf dem Bildschirm "Name" => "Name des Blabla" anzeigen. Ich verstehe, wie man mit Staat arbeitet, Redux verwendend, aber ich habe Schwierigkeiten, zu sehen, was mit diesen anderen Informationen tun muss, die ich noch in der Anwendung fortpflanzen muss, aber nicht wirklich Staat ist.

+0

Auf den ersten Blick, die mir wie Zustand zu sein scheint. Welchen Einwand haben Sie, "Name" in Staat zu setzen? –

+0

Der Name selbst ist in der Tat State, aber das "Label" dieser Name Eigenschaft ist nicht Staat. Es handelt sich um Informationen zu den Eigenschaften im Modell. –

+0

Wenn das "Label" des Namens als Requisite in einer Komponente verwendet wird, würde ich sagen, dass es sich um einen Zustand handelt. –

Antwort

11

Laut Redux ist der Staat die einzige "Quelle der Wahrheit". Und es sollte keine Doppelarbeit geben (was zu Inkonsistenzen führen würde).

So sollte Ihr Zustand die name, aber nicht die berechnete Label-Eigenschaft speichern.

In der Tat, "Name des Blabla" ist eine Funktion (im mathematischen Sinne) Ihres Namens Wert, und wenn sie sich unterscheiden (zum Beispiel, wenn an einem bestimmten Punkt === "foo" aber die Bezeichnung ist ' Name der Bar 'statt' Name des Foo '), dann haben Sie ein Problem ...

Also was ich tun würde, ist nur speichern Sie das Minimum in Ihrem Zustand (Name in diesem Fall), und berechnen das Label direkt in der Komponente, wo Sie es brauchen.

Wenn Sie das zur Wiederverwendung benötigen, dann erstellen Sie eine Komponente, die nur Ihren Namen als Requisite nimmt, und rendern Sie eine Zeichenfolge mit "Name der Blabla" (wenn Name = blabla ich nehme an).

Wenn Sie komplexere Berechnungen benötigen (sagen Sie, dass Sie mehrere Beschriftungen, Datumsberechnungen usw. haben), können Sie immer eine Funktion erstellen, die Ihren Zustand in Eingabe nimmt und Ihr "Modell" in Ausgabe ausgibt.

Redux ist sehr funktionell in der Natur, so dass Sie könnte es auch umarmen :)

+0

Ich glaube, ich bevorzuge diesen Ansatz. –

+0

Warum können wir den Teilbaum selbst nicht als unveränderliches Modell betrachten? – Nishant

6

Ich weiß, ich bin ein bisschen spät, um die Partei, aber ich dachte, jemand die Antwort verwenden könnte. Was für mich hat Arbeit dieser weit nach nun schon seit einigen Jahren mit React arbeiten, ist eine Struktur zu haben, die Art, wie das ist:

  • Zustand: die die Struktur (oder ‚Schemata‘) meiner Daten setzt.
  • Aktionen: Nehmen Sie Änderungen an diesem Status vor. Diese Aktionen können Sync- oder Async-Vorgänge verarbeiten.
  • Sagas: Sie behandeln asynchrone Aktionen.
  • Selektoren: Sie behandeln die Struktur der Daten, die ich für die Ansicht/für die API brauche.
  • Konstanten: andere Daten, die sich nicht im Laufe der Zeit ändern und es macht keinen Sinn, meinem Zustand hinzuzufügen.

So gesagt hat, dass der Fluss von meinen apps so etwas wie diese: Ein ACTION versandt => Wenn diese Aktion async ein SAGA ist zuhört und sie den Betrieb holen führt => Diese Saga Aktualisierungen der spart STATE => [Komponentenlayer ab jetzt bearbeiten] => Wenn meine Ansicht die Daten aus meinem Zustand in einem anderen Format benötigt, sende ich sie über eine SELECTOR, die dieses Format ändert => Dann füge ich diese neuen geparsten Daten an meine Behälterkomponente.

Ein anderer Fluss könnte einer sein, in dem Sie statische Daten benötigen, die nicht in Ihrem state sind. In diesem Fall würde ich es in einem Objekt in einer separaten Datei speichern und würde es direkt in meine Container-Komponente importieren (ich importiere nie irgendetwas direkt in meine Kinder/Präsentations-Komponenten. Nur andere Komponenten. Die Daten werden in einer separaten Ebene behandelt als die Komponenten).

Eine dritte Art von Flow, die ich mir gerade vorstellen kann, ist, wenn Sie einen POST an Ihre API machen müssen und aus welchem ​​Grund auch immer die Daten in Ihrem Zustand ein Parsing benötigen. In diesem Fall würde ich das gleiche tun, wie im ersten Beispiel, aber andersherum: Versende eine ACTION => das wird von einer SAGA => erledigt, bevor ich die Daten holen würde, würde ich meine Daten für meinen POST schon strukturieren (sagas hat eine Methode namens select, um Ihnen zu helfen, hier Selektoren zu verwenden) => dann würde ich die asynchrone Operation durchführen => den Zustand entsprechend aktualisieren.

Gerade falls Sie nicht wissen, was ich von Selektoren oder Sagas einige Links hier bedeuten:

1

Ich denke Modelle sind notwendig für eine Redux-basierte App wie für jedes andere System.

Modelle sind das Vokabular eines Systems. Modelle bringen Vernunft in die Codebasis. Ohne sie sieht eine Codebasis wie eine Reihe verrückter verzerrter Gedanken aus.

Sie können Statusfunktionen verwenden, um Modelle in ReactJS + Redux-Apps zu füllen. Genau wie Modelle Daten und Methoden enthalten, enthalten diese Objekte nur die Funktionen, die auf den Zustand angewendet werden können.

Lesen Sie hier: https://medium.com/@nshnt/state-functions-for-modeling-with-redux-a9b9d452a631.

ist hier das berühmte Redux ERLEDIGT app Beispiel mit staatlichen Funktionen:

todo_reducer.js:

import TODO from './todo_state'; 

const todoListReducer = (state=TODO.initialState(), action)=>{ 
    switch(action.type){ 

    case 'ADD_TODO' : 
     return TODO.addTask(state, action.taskName); 

    case 'FINISHED_TODO': 
     return TODO.setFinished(state, action.taskID); 

    case 'PENDING_TODO': 
     return TODO.setPending(state, action.taskID); 

    default : 
     return state; 
    } 
}; 

export default todoListReducer; 

todo-state.js:

export default { 
    initialState:() => [], 

    addTask: (todoList, name)=> todoList.concat({id: todoList.length, name: name}), 

    setFinished: (todoList, taskId) => (
     todoList.map(task=> task.id === taskId ? {...task, complete: true} : task) 
), 

    setPending: (todoList, taskId) => (
     todoList.map(task=> task.id === taskId ? {...task, complete: false} : task) 
), 

    pending: todoList=> todoList.filter(task=> !task.complete) 

}; 

ich auch Verwenden Sie diese Statusfunktionen in der Komponente, wenn die Komponente eine Zustandsänderung benötigt.

todo_list.js:

import React from 'react'; 
import {connect} from 'react-redux'; 
import TODO from './todo_state'; 

const TodoList = ({tasks, showCompletedTasks, toggleTodo})=> { 
    const toListElement = (task) => (
     <li key={task.id}> 
     <input type="checkbox" checked={task.complete} onChange={(e)=> toggleTodo(task)}/> 
     <label>{task.name} {task.complete ? "Complete" : "Pending"}</label> 
     </li> 
); 
    const visibleTaskList = 
     (showCompletedTasks ? tasks 
     : TODO.pending(tasks)).map(toListElement); 

    return (
     <ul className="todo-list"> 
     {visibleTaskList} 
     </ul> 
); 
} 
..... 
export default connect(mapStateToProps, mapDispatchToProps)(TodoList);