Als ReactJS Identifizierung (und andere Flußmittel Implementierungen, wie redux) empfohlen:Problem mit der minimalen Darstellung Zustand
Wir should't einen Zustand zu halten, die aus anderen Zustand berechnet werden kann (wir nennen es abgeleitete Daten), andernfalls müssen wir, wenn wir einen Zustand setzen, einen anderen setzen.
Aber betrachten Sie das folgende Beispiel:
Es gibt 2 Zustände in meiner Seite
- Die Farbe der Ampel: Licht = rot/grün
- Gibt es Leute kommen auf der anderen seite: people = true (es gibt menschen)/false (menschenleer)
Wie wir wissen, können die Leute nicht über die Straße kommen, wenn die Ampel rot ist.
So, haben wir 3 normale kombinierten Zustände:
- Licht = grün und Menschen = true
- Licht = grün und Menschen = false
- Licht = rot und Menschen = falsch
Der andere Zustand light = red und people = true ist ungültig.
Wir berechnen Menschen = false wenn Licht = red, in diesem Fall Menschen ein abgeleiteten Daten von Licht sind. Aber wenn Licht = grün können wir nicht.
Das Problem ist, wenn ich den Licht Wert gesetzt, ich habe die Menschen Wert zu setzen, sonst wird es zu einem ungültigen Zustand führen kann.
So, wie um dieses Problem zu lösen? Wie gestalte ich meinen Staat?
Gibt es eine Bibliothek, die hilft, sie zu verwalten. Zuerst kann ich die Abhängigkeiten zwischen meinen Zuständen definieren. Die Bibliothek ist eine Antwort auf die Konsistenz von ihnen. Wenn ich einen Statuswert festlege, der im Konflikt mit anderen steht, werden andere auf den richtigen Wert geändert.
Ich habe ein einfaches Beispiel geschrieben, um zu zeigen, was ich will, gibt es eine solche Bibliothek?nur
class ComplexState {
constructor(config, initialState){
this.config = config;
this.state = initialState;
this._checkAll();
}
setState(key, value){
var config = this.config[key];
if(config && config.type === ComplexState.Types.Enum){
//Set Enum data type
if(Array.isArray(config.definitionField) && config.definitionField.indexOf(value) !== -1 ||
config.definitionField[value] && typeof config.definitionField[value].checker === 'function' && config.definitionField[value].checker(this.state)){
//Set the value
this.state[key] = value;
//If there is a conflict, modify other values
Object.keys(this.state).forEach(_key => {
if(key === _key){//Self
return;
}
var _value = this.state[_key];
var _config = this.config[_key];
if(!Array.isArray(_config.definitionField) && _config.definitionField[_value] && typeof _config.definitionField[_value].checker === 'function' && !_config.definitionField[_value].checker(this.state)){
//Conflict, adapt to correct value
this.state[_key] = _config.definitionField[_value].adapter(this.state);
}
})
//Check for conflicts
this._checkAll();
}else{
//Invalid value
}
}
}
getState(){
return Object.assign({}, this.state);
}
//Check for conflicts
_checkAll(){
Object.keys(this.state).forEach(_key => {
var _value = this.state[_key];
var _config = this.config[_key];
if(!Array.isArray(_config.definitionField) && _config.definitionField[_value] && typeof _config.definitionField[_value].checker === 'function' && !_config.definitionField[_value].checker(this.state)){
//Conflict
throw new Error('invalid state' + JSON.stringify(this.state));
}
})
}
}
ComplexState.Types = {
Enum : 0
}
es verwenden,
var myStates = new ComplexState({
light : {
type : ComplexState.Types.Enum,
definitionField : ['red', 'green']
},
people : {
type : ComplexState.Types.Enum,
definitionField : {
'false' : null,
'true' : {
checker : function(state){
return state.light !== 'red';
},
adapter : function(state){
if(state.light === 'red'){
return 'false';
}
return state.people;
}
}
}
}
}, {
light : 'Green',
people : 'false'
})
console.log(myStates.getState());//{light: "Green", people: "false"}
myStates.setState('people', 'true');
console.log(myStates.getState());//{light: "Green", people: "true"}
//when I set light value to red, the people value is automatically set to false
myStates.setState('light', 'red');
console.log(myStates.getState());//{light: "red", people: "false"}
Licht zu einem Bool, wo wahr ist grün und rot ist falsch, sollte dies zu lösen. Wenn Sie immer (Licht && Menschen) bewerten, dann ist der einzige wahre Wert, wenn das Licht grün ist und es Menschen gibt. – Chase
Ich glaube, du hast missverstanden, was ich meine. Bewerten (Licht && Menschen) ist bedeutungslos, es ist kein Ausdruck. Sie sind nur zwei Zustände auf meiner Seite und können unabhängig voneinander eingestellt werden. Ich habe meine Beschreibung bearbeitet, um das Symbol & zu entfernen. – junhan
Ich verstehe, aber was Sie suchen, ist, gibt es Menschen in der Kreuzung. Was möchten Sie tun, um jeden Wert unabhängig voneinander korrigieren zu können? 'sind da Leute in der Kreuzung 'sind die abgeleiteten Daten, die immer von (light && people) ausgewertet werden können. Jeder schützt den anderen, sodass Sie diese beiden Werte unabhängig voneinander in Ihrer App ändern können. Die einzigen zwei Statuswerte, die du brauchst, sind Licht und Menschen, solange du immer "Menschen in der Kreuzung" von dem Ausdruck (Licht && Menschen) ableitet. – Chase