States, Redux... ein Selbstversuch
Ich habe mit Hilfe von anderen Seiten dann heraus bekommen. Dass Redux einen State pro Reducer hält und der alle Actions bekommt und dann mit eigener Logik, die für ihn interessanten Actions ab arbeitet. Alter State geht rein und neuer geht raus. Eine Action hat einen Typ und ein Payload. Wenn sich der State ändert, wird etwas getriggert. Aber ich fand, dass doch für einfache Beispiele zu viel Code da war um es zu verstehen.
Um also das Prinzip von Redux zu verstehen habe ich dann mal 20min investiert und mir ein ähnliches Kontrukt geschaffen. Etwas Topic orientierter mit den States, so dass man die Reducer pro Action hat, aber vom Prinzip ist es alles relativ einfach und das Bootstrapping wurde daruch auch übersichtlicher.
Die meisten Beispiele zu Redux bestehen sowie so zu 50% aus React. Aber ich wollte ja Redux verstehen und nicht Redux+React (ja.. die gibt es wirklich auf getrennt von einander!)
Hier das Ergebnis meines Selbstversuches:
const StateStore = {
states: {},
actions: {},
createState: function(name){
this.states[name] = {
data: null,
workers: [],
listeners: []
}
},
registerWorker: function(statename, action, worker){
if(this.states[statename]){
if(!this.states[statename].workers[action]){
this.states[statename].workers[action] = []
}
this.states[statename].workers[action].push(worker);
if(!this.actions[action]){
this.actions[action] = [];
}
this.actions[action].push(statename);
}
},
registerListener: function(statename, listener){
if(this.states[statename]){
this.states[statename].listeners.push(listener);
}
},
action: function(action, payload){
if(this.actions[action]){
this.actions[action].forEach((statename) => {
let changes = false;
this.states[statename].workers[action].forEach((worker) => {
const stateCopy = JSON.parse(JSON.stringify(this.states[statename].data));
let newState = worker(this.states[statename].data, payload);
if(newState != stateCopy){
changes = true;
}
this.states[statename].data = newState;
});
if(changes){
this.states[statename].listeners.forEach((func) => {func(this.states[statename].data)});
}
});
}
}
};
Dazu mein kleiner Test:
StateStore.createState("test");
StateStore.registerWorker("test", "inc", (state, payload) => {
if(state === null){
return 0;
}
else {
return ++state;
}
});
StateStore.registerWorker("test", "dec", (state, payload) => {
if(state === null){
return 0;
}
else {
return --state;
}
});
StateStore.registerWorker("test", "dn", (state, payload) => {
console.log("(" + state + ") do nothing");
//change-listeners are not triggert
return state;
});
StateStore.registerListener("test", (state) => {console.log(state)});
StateStore.action("inc", null); //0
StateStore.action("inc", null); //1
StateStore.action("inc", null); //2
StateStore.action("dn", null); //(2) do nothing
StateStore.action("inc", null); //3
StateStore.action("dec", null); //2
Lief erstaunlicher Weise direkt wie es sollte (nach dem ein kleiner Fehler bei einer falschen Variablen behoben war).
Damit sollte man durch aus das gesamte Statemanagement einer Componente abbilden können. Wenn man nun noch Events verwenden würde, geht es schon stark in Richtung Reactive-Programming.
https://github.com/annonyme/jsstatestore