States, Redux... ein Selbstversuch

Heute saß ich vor der Dokumentation zu den neuen Hooks bei React und las mit durch welche Probleme die alle lösen sollen. Indirekt wurde gesagt, dass sie Redux unnötig machen sollen.. also war für mich die Zeit gekommen mir wirklich mal Redux anzusehen. Erstmal zu verstehen, was es tut, ist nicht ganz so einfach, wenn man sich deren Doku durchliest. Was gefühlt aber nur an deren Doku liegt, die viel zu zerstückelt ist, um einen schnellen Überblick zu bekommen.

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


bbcode-image


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
User annonyme 2019-02-01 17:23

write comment:
Three + = 4

Möchtest Du AdSense-Werbung erlauben und mir damit helfen die laufenden Kosten des Blogs tragen zu können?