2016-03-27 54 views
1

Ich bin neu in Redux Welt und ich versuche, Zeitung App zu machen. Ich arbeite derzeit an der Suchfunktion, wo der Benutzer nach bestimmten Zeitungstiteln suchen kann. Das Problem ist, dass, wenn ich zuerst "a" eintippe, der Zustand "" ist. Und wenn ich zB "b" tippe, zeigt der Staat, dass der Begriff "a" ist, wenn er "ab" sein soll. Ich verwende Redux Chrome Tools, um diesen globalen Zustand zu überprüfen.Redux/React - Suchfeld aktualisiert den Redux-Status nicht sofort

Mein Actioncreator ist wirklich einfach (nur kehrt der Begriff an sie übergeben):

export function search(term) { 
    return{ 
    type:SEARCH, 
    term 
    } 
} 

Hier ist die Minderer:

const SearchReducer = (state = '', action) => { 

    switch (action.type) { 
     case SEARCH: 
      return action.term; 
     default: 
      return state; 
    } 

} 

Hier ist die Wurzel Minderer:

/*Application state*/ 
const rootReducer = combineReducers({ 
    weather: WeatherReducer, 
    filters: FilterReducer, 
    articles:ArticleReducer, 
    search: SearchReducer // this should be 'ab', but is 'a' 
}); 

Das ist wirklich einfache Einrichtung. Hier ist, wie ich mit Redux kommuniziere.

ich mein Material-ui Textfeld haben (ich versuchte, Vanille-Eingabefeld auch)

<TextField style={style.searchWidget.search} 
      floatingLabelText="Search" 
      value={this.state.term} 
      onChange={this._onSearchChange} 
/> 

, wenn der Benutzer etwas die _onSearchChange func abgefeuert wird.

_onSearchChange(event) { 
    this.setState({term: event.target.value}); 
    this.props.search(this.state.term); 
} 

Dies wird den aktuellen Status für diese Suchkomponente festlegen. Dann wird eine Suchaktion ausgelöst, die den globalen Status aktualisiert. Aber funktioniert nicht richtig. Der globale Staat ist immer 1 Schritt zurück.

Irgendeine Idee?

Edit: Es sieht aus wie es ist nicht Redux aber reagieren. Der Komponentenstatus wird nicht sofort aktualisiert. Der korrekte Ausdruck wird an den actionreducer übergeben, so dass es nicht redux ist. Ich habe versucht, dieses.state.term auszudrucken, nachdem ich den Zustand eingestellt habe. Und es sieht so aus, als ob der Status nicht aktualisiert wird.

Antwort

1

Eigentlich ist es nicht mit Redox verwandt. Sie müssen sich bei der Arbeit mit react daran erinnern, dass Sie den aktualisierten Status nicht erhalten, sobald Sie Ihren Reaktionszustand aktualisieren. Nehmen wir ein Beispiel.

getInitialState: function() { 
    return { 
    myState: 0 
    } 
}, 

updateState: function(stateVersion) { 
    console.log(this.state.myState); //this will print 0 
    this.setState({ myState: stateVersion }); 
    console.log(this.state.myState); //this will print 0 
} 

jetzt zum ersten Mal, wenn wir update Funktion mit state-Version als Argument nennen es 0 sowohl für die Konsole aus, auch wenn wir 1 oder 2 oder eine beliebige Zahl als Argument gesendet. Angenommen, wir haben 2 als Argument gesendet. dann können wir diesen Zustand im nächsten Aufruf dieser Funktion mit anderen Argumenten erhalten. Aber reagiere auch darauf. Sie können denken, dass, wenn der Zustand nicht aktualisiert wird, sobald wir das aktualisieren, wie kann ich damit arbeiten. Aber reagieren ist ein guter Junge ... Wenn Sie eine Funktion aufrufen, um einen Zustand zu aktualisieren, und dann rufen Sie eine andere Funktion auf, um mit dem letzten aktualisierten Status zu arbeiten, dann können Sie damit arbeiten.

Ich denke, ich habe bereits Ihre Frage beantwortet, warum nicht Redux State aktualisiert wird.

ein anderer Gedanke ist, dass, wenn Sie Redux-Zustand für Ihre Suche Reducer dann verwenden, warum Sie auch reagieren Zustand handhaben. Sie können die gesuchten Parameter direkt in Ihre Aktion übernehmen. Sie können dieses Update sofort von Ihrem Reduziererstatus erhalten. Es wird Ihrem Code Einfachheit helfen.

+0

Danke für den Tipp. Es funktioniert gut :) – onurhb

0

Ich fand die Lösung. React - State not updated Es scheint, dass der setState tatsächlich nicht sofort den Status setzt. Also habe ich stattdessen eine Callback-Funktion verwendet. Jetzt

_onSearchChange(event) { 
    this.setState({term: event.target.value}, function() { 
     console.log(this.state.term) 
    }); 
    } 

, wenn ich schreibe 'a' wird log 'a'!

+0

Bei diesem Ansatz würde ich immer noch empfehlen, sicherzustellen, dass Sie den Ansatz "Dispatch-Aktion" verwenden, da Sie Redux verwenden. Wenn Sie jedoch den Status verwenden, um die Eingabe festzulegen (was Sie möglicherweise tun?), Dann stellen Sie sicher, dass neue Requisiten diese Änderung außer Kraft setzen, wenn sie von oben herunterkommen. Dies erscheint mir als eine Art "optimistische Wiedergabe/Aktualisierung". Wenn Sie also den Status verwenden, um die Eingabe festzulegen, müssen Sie sicherstellen, dass der lokale Status der Komponente aktualisiert werden kann, wenn newProps aus dem Redux-Flow eingeht. – marcacyr

+0

Wenn Sie den Status jedoch nicht zum Festlegen der Eingabe verwenden, können Sie davon profitieren, einen Rückruf in setState zu verwenden und nur den Versand aus dem Redux-Shop zu verwenden (wie ich in meiner Antwort oben erwähnt habe). Anfang dieser Woche habe ich eine Frage gestellt (persönlich, nicht auf SO) darüber, warum/wann die Option für einen Callback auf 'setState' verwendet werden soll. Nach der Erläuterung der Reihenfolge, in der die Methoden ausgelöst werden, und wenn der Callback tatsächlich aufgerufen wird, kam ich zu dem Schluss: "Die Verwendung von Redux macht normalerweise solche Umgehungen wie das Hinzufügen eines Callbacks zu Ihrem' setState'-Aufruf unnötig. " – marcacyr

3

Diese Antwort fügt ein bisschen hinzu, was Aniket Nandan darauf hingewiesen - Sie verwenden SetState innerhalb Ihrer React-Komponente, anstatt sich auf Requisiten von oben zu verlassen.

Der Hauptzweck der Verwendung von Redux besteht darin, Ihren Status zu nehmen und in einen Container neben der Anwendung zu legen. Der Vorteil dabei ist, dass Ihr Status über mehrere Komponenten verteilt werden kann und Sie dann Dinge über Requisiten in die Komponenten in Ihrer Komponentenstruktur übertragen können.

Die Verwendung eines Zustandscontainers (der mich immer ein bisschen an die Verwendung von Zustandsautomaten erinnert hat) ermöglicht es Ihnen, Ihre Anwendung ohne die Kompliziertheit zu erstellen, Callbacks durch den Baum zu übergeben, um Änderungen zu erhalten, um zurück zu gehen oben. Stattdessen behandelt Redux die Statusänderungen und übergibt alles wieder Reagieren durch Requisiten.

_onSearchChange(event) { 
    this.setState({term: event.target.value}); 
    this.props.search(this.state.term); 
} 

In diesem Sinne oben Blick auf den Code, aus Ihrem Post, frage ich mich, warum Sie mit dem Begriff SetState, aber dann rufen immer eine Funktion, die Sie durch Requisiten erhalten? Ruft die Suche dann die Versandmethode aus dem Redux-Speicher auf? Wenn nicht, dann sind Sie nicht richtig verkabelt.

Weiter zu diesem Punkt, wenn Sie connect korrekt verwendet haben (von react-redux), dann sollten Sie die Dispatch-Methode aus dem Redux-Speicher verfügbar haben (dies geschieht durch Kontext).

Die Art und Weise Redux zu arbeiten konzipiert ist so etwas wie diese:

_onSearchChange(event) { 
    this.props.dispatch({ type: 'SEARCH', term: event.target.value }); 
} 

Was dann Redux sollte den Staat Updates behandeln, und der neue Zustand fließt von Redux über Requisiten zu reagieren (das passieren würde passiert durch alle Verbindungen unter der Haube in Redux, die ziemlich fantastisch ist!).

const SearchReducer = (state = '', action) => { 

    switch (action.type) { 
     case SEARCH: 
      return action.term; 
      break; 
     default: 
      return state; 
    } 

} 

Basierend auf Ihrem Minderer (kopiert oben ^^) und die Nutzung von combineReducers, sollten Sie mit einem Zustand enden, die { search: { term: 'ab' } } hat, wenn Sie ‚ab‘ eingegeben hat, und es sollte nur nach der Eingabe von ‚a‘ sein "a", anstatt zurückbleiben.

Was eigentlich mit Ihrer Verwendung von setState und der Methode von Requisiten geschah war der Anfangszustand (ich gehe davon aus '') wurde an this.props.search übergeben, das erste Mal. In der Zwischenzeit wurde der Zustand auf 'a' aktualisiert, nachdem Sie "a" eingegeben haben. Dann, beim nächsten Mal, als Sie 'b' eintippten, wurde der Zustand auf 'ab' aktualisiert, aber this.props.search empfing nur die Bedingung aus dem Zustand, bevor die setState fertig ausgeführt wurde - während es immer noch 'a' war.

Dies ist einer der Gründe, warum Redux so großartig ist - es bietet eine Möglichkeit, sicherzustellen, dass der Status ordnungsgemäß anhand von Benutzeraktionen innerhalb seines eigenen Containers aktualisiert wird. So können Sie gewährleisten, dass die Dinge in Ihrer Anwendung synchron sind .

In diesem Sinne werde ich einen Tipp für die Arbeit mit Redux hinterlassen: Sie sollten selten finden setState innerhalb einer React-Komponente, die in einer Anwendung mit Redux ist. Die Entscheidung, wann setState in einer Komponente verwendet werden soll, hängt davon ab, ob die gewünschte Statuskomponente nur in dieser Komponente vorhanden ist und der Rest der Anwendung nicht darüber informiert werden muss. Ich kann mir kein Beispiel vorstellen, und alles, was ich anbieten könnte, wäre wahrscheinlich ziemlich erfunden. Der Grund, warum ich nicht an einen solchen Punkt denke, ist, dass ich denke, dass es eine Seltenheit ist, dass Sie einen solchen Anwendungsfall in einer Anwendung haben.

Sie sollten also nur die Versandmethode aus dem Redux-Store verwenden und Redux erlauben, die Statusaktualisierungen über seinen Workflow zu verarbeiten und den Status über Props nach unten zu den Komponenten fließen zu lassen. Wenn Sie sich an diesen Fluss halten, werden viele dieser seltsamen Probleme, die auftreten können, verhindert.

+0

Danke für Ihre Zeit Ich sehe die Dinge jetzt klar! – onurhb

Verwandte Themen